gpt4 book ai didi

c++ - 未命名命名空间中符号的模板访问

转载 作者:行者123 更新时间:2023-11-30 01:31:53 25 4
gpt4 key购买 nike

我们正在将我们的 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" 移动到未命名 namespace 声明之后,编译错误就会消失。

所以这是我的问题:标准对此有何看法?当一个模板被实例化时,该实例是否被认为是在模板本身被声明的地方声明的,或者标准在这一点上不是很清楚?我仔细查看了 n2461.pdf 草稿,但并没有真正得出任何确定的结论。

最佳答案

这不是有效的 C++ 代码。 TEST 不依赖于模板参数 T,因此在解析时必须在模板定义的上下文中找到它。但是,在该上下文中,不存在 TEST 声明,因此会出现错误。

该格式错误的模板的诊断消息可以延迟到编译器实例化之前,但如果编译器是好的,它会更早地诊断出错误。即使在实例化模板时也不为该代码提供任何诊断消息的编译器是不符合要求的。它与未命名的命名空间无关。

此外,请注意,即使您将未命名的命名空间放在该模板之上,如果您在多个翻译单元中定义和调用该模板,它也不是有效的 C++ 程序。这是因为具有相同模板参数的相同模板的不同实例将引用不同的事物(未命名命名空间中的字符串每次在另一个翻译单元中定义时都会产生不同的对象)。这种程序的行为是不确定的。

关于c++ - 未命名命名空间中符号的模板访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2525984/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com