Мы обновляем наш компилятор XL C / C ++ с V8.0 до V10.1 и обнаружили некоторый код, который теперь выдает нам ошибку, даже если он скомпилирован под V8.0. Вот минимальный пример:
test.h:
#include <iostream>
#include <string>
template <class T>
void f()
{
std::cout << TEST << std::endl;
}
test.cpp:
#include <string>
#include "test.h"
namespace
{
std::string TEST = "test";
}
int main()
{
f<int>();
return 0;
}
В V10.1 мы получаем следующую ошибку:
"test.h", line 7.16: 1540-0274 (S) The name lookup for "TEST" did not find a declaration.
"test.cpp", line 6.15: 1540-1303 (I) "std::string TEST" is not visible.
"test.h", line 5.6: 1540-0700 (I) The previous message was produced while processing "f<int>()".
"test.cpp", line 11.3: 1540-0700 (I) The previous message was produced while processing "main()".
Мы обнаружили аналогичное различие между g ++ 3.3.2 и 4.3.2. В g ++ я также обнаружил, что если я переместу #include "test.h"
после объявления безымянного пространства имен, ошибка компиляции исчезнет.
Итак, вот мой вопрос: что Стандарт говорит об этом? Когда создается экземпляр шаблона, считается ли этот экземпляр объявленным в тот момент, когда был объявлен сам шаблон, или стандарт не очень ясен по этому вопросу? Я хоть немного посмотрел черновик n2461.pdf, но ничего не смог придумать.