На самом деле приведенный ниже код нельзя скомпилировать с помощью Clang с помощью этой команды:
clang++ -std=c++11 test.cc -o test
.
Я просто хочу имитировать то же поведение, что и идиома подкачки в C++, чтобы использовать директиву использования для включения ADL. Но где я ошибаюсь в следующем коде? Ожидаемый приоритет вызова должен быть следующим: N1::foo
› N2::foo
› ::foo
, верно?
namespace N1 {
struct S {};
void foo(S s) {
std::cout << "called N1::foo.";
}
}
namespace N2 {
void foo(N1::S s) {
std::cout << "called N2::foo.";
}
}
void foo(N1::S s) {
std::cout << "called foo.";
}
int main() {
using N2::foo;
foo(N1::S{});
}
Сообщения об ошибках:
test.cc:54:3: error: call to 'foo' is ambiguous
foo(N1::S{});
^~~
test.cc:40:8: note: candidate function
void foo(S s) {
^
test.cc:45:8: note: candidate function
void foo(N1::S s) {
^
1 error generated.
Обновлено:
Я изменил N2::foo на метод шаблона, который может до некоторой степени имитировать std::swap. Итак, вопрос здесь в том, почему ::foo
не может вызываться foo(N1::S{});
в функции main
? Поскольку функция должна быть намного более правильной, чем функция шаблона, которую нужно вызывать, когда они имеют одинаковый приоритет.
namespace N1 {
struct S {};
/*
void foo(S s) {
std::cout << "called N1::foo, specific one." << '\n';
}
*/
}
namespace N2 { // as a fallback to unqualified name which has no user-defined overload.
template<typename T>
void foo(T) {
std::cout << "called N2::foo, generic one." << '\n';
}
}
void foo(N1::S s) {
std::cout << "called foo." << '\n';
}
int main() {
using N2::foo;
foo(N1::S{});
foo(10); // use generic version.
}