У меня возникла проблема в каком-то производственном коде, который я минимизировал до следующего тестового примера:
template<typename T>
void intermediate(T t)
{
func(t); // line 4 ("func not declared in this scope")
}
namespace ns {
struct type {};
}
void func(ns::type const & p); // line 11 ("declared here, later")
void foo(ns::type exit_node)
{
intermediate(exit_node); // line 15 ("required from here")
}
GCC 4.5 компилирует этот штраф. Как с, так и без -std=c++11, 4.7 и 4.9 вызывают такие сообщения, как:
test.cpp: In instantiation of ‘void intermediate(T) [with T = ns::type]’:
test.cpp:15:27: required from here
test.cpp:4:5: error: ‘func’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
test.cpp:11:6: note: ‘void func(const ns::type&)’ declared here, later in the translation unit
Все три следующие вещи приведут к успешному компиляции файла:
- Переместите
func(ns::type)в пространство именns(позволяя ADL найти его вns) - Переместите
typeв глобальное пространство имен (позволяя ADL найти его в::) - Избавьтесь от
intermediateи вызовитеfuncнепосредственно изfoo
Итак... что здесь происходит? Является ли законным для GCC отказаться от этой программы? Почему func найден неквалифицированным поиском в третьем варианте (вызов func непосредственно из foo), но не найден неквалифицированным поиском в исходном варианте в момент создания экземпляра?