我发现这个奇怪的情况下某些代码(如下)不能在Visual Studio 2008下编译,并在第12行产生“错误C2872:'歧义':模糊符号”。
在最后一行删除使用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;
显然这是一个制造的示例,但原始内容是从using namespace
在第三方代码生成的自动生成文件中的实际案例中提取的。
这是编译器中的错误吗?
答案 0 :(得分:5)
我同意这是一个错误,但是通过生成与您的文件相对应的程序集列表(使用cl.exe的/ Fa选项)可以了解对正在发生的事情的一些了解。
因此,注释掉using声明,生成.asm文件并在文本编辑器中打开它。扫描文件,您可以看到模板的实例化位于文件的底部(以??$TemplatedFunction@H@Ambiguity@@YAXH@Z PROC
开头),它位于为主函数生成的程序集下(以_main PROC
开头)。错误消息说“请参阅函数模板实例化”,因此它指的是模板函数的实例化,汇编列表清楚地表明这个实例化位于文件的底部。
现在,编辑代码以用NonTemplatedFunction(int a)
替换模板函数并编译,生成程序集列表。查看汇编列表,您将看到为NonTemplatedFunction(int a)
生成的汇编代码显示在_main PROC
上方。
所有这些唠叨是什么意思?当Visual Studio 2008编译器将您的模板转换为实际代码时,它会在您使用声明后有效地将一些代码附加到文件的末尾。您的使用声明意味着自动生成的代码中的名称是“不明确的”。 gcc用于实例化模板的过程显然避免了这个问题。
答案 1 :(得分:2)
我认为这是一个错误,根据C ++ 03标准的7.3.4第1段:
using-directive指定指定命名空间中的名称可以在using-directive出现在using-directive之后的范围内使用。
因此,使用声明的文件结尾应该没有效果。