С учетом следующего кода:
#include <iostream>
struct Alice
{
template <typename A>
void operator|(const A& /*a*/) const
{
std::cout << "operator| member" << std::endl;
}
};
template <typename A>
void operator|(const A& /*a*/, const Alice& /*alice*/)
{
std::cout << "operator| non-member" << std::endl;
}
int main()
{
Alice a;
Alice b;
a | b;
return 0;
}
Он компилируется без предупреждения как с GCC 4.8.1, 4.9, так и с clang 3.4, но дает разные результаты.
$ g++ -Wall -Wextra -std=c++11 alice.cpp && ./a.out
operator| non-member
$ clang++ -Wall -Wextra -std=c++11 alice.cpp && ./a.out
operator| member
В чем причина этой разницы? Как я могу заставить одно и то же поведение?
EDIT: Интересный факт: удаление классификатора const
из функции-члена делает gcc также предпочтительной для функции-члена. Однако это не решает проблему.
EDIT: clang++ предпочитает не-член вместо этого, если -std=c++11
не указан.
РЕДАКТИРОВАТЬ: ICC 14.0 предпочитает не-член, не выдается предупреждение.