我们正在将我们的 XL C/C++ 编译器从 V8.0 升级到 V10.1,发现一些代码现在给我们一个错误,即使它是在 V8.0 下编译的。这是一个最小的例子:
测试.h:
#include <iostream>
#include <string>
template <class T>
void f()
{
std::cout << TEST << std::endl;
}
测试.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 草案,但并没有真正想出任何确定的东西。