符号在未命名命名空间中的模板访问 [英] Template access of symbol in unnamed namespace

查看:153
本文介绍了符号在未命名命名空间中的模板访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在将我们的XL C / C ++编译器从V8.0升级到V10.1,并发现一些代码现在给我们一个错误,即使它是在V8.0下编译。以下是一个最小示例:

We are upgrading our XL C/C++ compiler from V8.0 to V10.1 and found some code that is now giving us an error, even though it compiled under V8.0. Here's a minimal example:

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;
}
Under V10.1, we get the following error:
"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 ++中,如果我把 #includetest.h移到未命名的命名空间声明之后,编译错误就会消失。

We found a similar difference between g++ 3.3.2 and 4.3.2. I also found in g++, if I move the #include "test.h" to be after the unnamed namespace declaration, the compile error goes away.

所以这里是我的问题:标准是怎么说的?当模板被实例化时,被认为是在模板本身被声明的那一点被声明的实例,还是在这一点上不清楚的标准?我做了一些看看n2461.pdf草案,但没有真正想出任何确定的。

So here's my question: what does the Standard say about this? When a template is instantiated, is that instance considered to be declared at the point where the template itself was declared, or is the standard not that clear on this point? I did some looking though the n2461.pdf draft, but didn't really come up with anything definitive.

推荐答案

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

This is not valid C++ code. TEST is not dependent on the template parameter T, so it must be found in the context of the template definition when it's parsed. However, in that context no declaration of TEST exists, and so there is an error.

编译器可能会延迟该错误模板的诊断消息,直到实例化,但如果编译器正常,它会提前诊断错误。即使实例化模板时,不为该代码提供任何诊断消息的编译器不符合。它与未命名的命名空间无关。

The diagnostic message for that ill-formed template can be delayed until instantiation by the compiler, but if the compiler is good, it will diagnose the error earlier. Compilers that don't give any diagnostic message for that code even when the template is instantiated are not conforming. It has nothing to do with unnamed namespaces.

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

In addition, notice that even if you put the unnamed namespace above that template, it will not be a valid C++ program either if you define and call that template in multiple translation units. This is because different instantiations of the same template with the same template arguments will refer to different things (the string in the unnamed namespace will produce a different object each time it's defined in another translation unit). Behavior for such a program would be undefined.

这篇关于符号在未命名命名空间中的模板访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆