Когда компилятор пытается разрешить i.template hi<T>();
, он находит hi
в глобальном пространстве имен вместо метода hi
на i
(ideone). Почему?
#include <cstdio>
// Define 'hi' and 'bye' in the global namespace; these should *not* be used
template<typename T> struct hi { };
template<typename T> struct bye { };
// Foo needs to be templated for Foo::Inner to be a dependent type (I think)
template<typename T>
struct Foo
{
struct Inner {
// This is a plain-old templated member function of Inner, yes?
template<typename U>
void hi() { std::printf("hi!\n"); }
// This is a plain-old member function of Inner
void bye() { std::printf("bye!\n"); }
};
void sayStuff()
{
Inner i;
i.template hi<T>(); // Fails to compile -- finds global hi instead of member
i.bye(); // Compiles fine, finds member
}
};
int main() {
Foo<int> f;
f.sayStuff();
return 0;
}
Я использую g++ 4.9.1/4.9.2 (-std=c++11
). Точное сообщение об ошибке:
prog.cpp: In member function 'void Foo<T>::sayStuff()':
prog.cpp:19:5: error: invalid use of 'struct hi<T>'
i.template hi<T>();
^
Этот код отлично работает с Clang и VS2013, но генерирует ошибку в g++ и EDG. Но какие компиляторы правы?
Есть ли способ разрешить это, кроме изменения имени члена? В моем реальном коде конфликт возникает, когда тип из пространства имен std
(который был импортирован через using namespace std
, скажем) имеет то же имя, что и одна из моих функций-членов. Очевидно, мне хотелось бы, чтобы мой код реализации был надежным и не вызывал случайных конфликтов имен в коде пользователя.