From a conversation in a different thread with adam2016, I realized I don't understand why standard is choosing one seemingly ambiguous overload over another. I contrived a simpler example to show what I dont understand.
Can someone explain why it is choosing the template non-member function over the member function, and if possible, link an article or standard clause that explains it.
The following creates an infinte loop, recursively calling
void bar(Widgdet& a, Widget& b);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
// Example program
#include <iostream>
namespace gadget {
template <typename T>
void bar(T&, T&)
{
std::cout << "In template foo(T&, T&) where T = Widget" << std::endl;
}
}
struct Widget {
void foo(Widget b)
{
std::cout << "In foo(Widget b)" << std::endl;
bar(*this, b);
}
void bar(Widget& a, Widget& b)
{
std::cout << "in bar(Widget& a, Widget& b)" << std::endl;
//using gadget::bar;
bar(a, b);
}
};
int main()
{
Widget w;
Widget v;
w.foo(v);
}
|
The following will not create an infinite loop, it calls
gadget::bar(T&, T&) where
T = Widget.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
// Example program
#include <iostream>
namespace gadget {
template <typename T>
void bar(T&, T&)
{
std::cout << "In template foo(T&, T&) where T = Widget" << std::endl;
}
}
struct Widget {
void foo(Widget b)
{
std::cout << "In foo(Widget b)" << std::endl;
bar(*this, b);
}
void bar(Widget& a, Widget& b)
{
std::cout << "in bar(Widget& a, Widget& b)" << std::endl;
using gadget::bar;
bar(a, b);
}
};
int main()
{
Widget w;
Widget v;
w.foo(v);
}
|
Why does it prefer the non-member function over the member function?
(Yes, I realize to stop the ambiguity, you can do Widget::bar(a, b), but my question remains).
_______________________________________
I assume that there's some sort of rule where it says "
If there is an ambiguity with X, but you have using my_namespace::X;
", it will always prefer the namespaced overload? But I'm not sure.