У меня возникла проблема в каком-то производственном коде, который я минимизировал до следующего тестового примера:
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
), но не найден неквалифицированным поиском в исходном варианте в момент создания экземпляра?