eAi*_*eAi 5 c++ compiler-construction templates namespaces
我发现的一些代码(下)这个奇怪的情况下,Visual Studio 2008的下无法编译,并产生一个"错误C2872:'模糊’:不明确的符号"第12行.
删除namespace RequiredNamespace最后一行的使用可以修复错误,但是我希望放在using namespace文件末尾应该没有效果.这也依赖于AnotherFunction作为一个模板函数,所以我希望编译器产生错误的范围模板的功能,或者不复位这样做之前所使用的命名空间的列表.
相同的代码在GCC下编译.
这两种编译器似乎生成的代码TemplatedFunction后using namespace Namespace的定义,至少据我可以通过引入错误,看着他们输出的顺序告诉.
namespace Ambiguity
{
class cSomeClass
{
};
template<class T>
void TemplatedFunction(T a)
{
// this is where the error occurs, the compiler thinks Ambiguity
// might refer to the class in RequiredNamespace below
Ambiguity::cSomeClass();
}
}
namespace RequiredNamespace
{
// without a namespace around this class, the Ambiguity class
// and namespace collide
class Ambiguity
{
};
}
int main()
{
// to force the templated function to be generated
Ambiguity::TemplatedFunction(4);
}
// removing this removes the error, but it shouldn't really do anything
using namespace RequiredNamespace;
Run Code Online (Sandbox Code Playgroud)
显然,这是制造的例子,但原稿从其中一个真实的情况下提取的using namespace是在由第三方代码产生一个自动生成的文件.
这是编译器中的错误吗?
我同意这是一个错误,但通过生成与您的文件对应的程序集列表(使用cl.exe的/ Fa选项)可以了解对正在发生的事情的一些了解.
因此,注释掉using声明,生成.asm文件并在文本编辑器中打开它.扫描文件,您可以看到模板的实例化位于文件的底部(以它开头??$TemplatedFunction@H@Ambiguity@@YAXH@Z PROC),并且它位于为main函数生成的程序集之下(以...开头_main PROC).错误消息表示"请参阅函数模板实例化",因此它指的是模板函数的实例化,并且汇编列表清楚地表明此实例化位于文件的底部.
现在,编辑代码以替换模板函数NonTemplatedFunction(int a)并编译,生成程序集列表.查看装配清单,您将看到NonTemplatedFunction(int a)上面显示的汇编代码_main PROC.
所有这些唠叨是什么意思?当Visual Studio 2008编译器将您的模板转换为实际代码时,它会在您使用声明后有效地将一些代码附加到文件的末尾.您的使用声明意味着自动生成的代码中的名称是"不明确的".gcc用于实例化模板的过程显然避免了这个问题.
根据 C++03 标准 7.3.4 第 1 条,我认为这是一个错误:
using 指令指定指定命名空间中的名称可以在该 using 指令出现在 using 指令之后的范围内使用。
所以你的文件结尾 using 声明应该没有效果。