C++ 嵌套的名称空间和不明确的符号
我有一个涉及嵌套名称空间和模板类的问题。我还能够创建测试用例,它产生与实际代码相同的错误,但可读性更强 使用VS2012和2010平台工具集编译以下代码会导致错误:C++ 嵌套的名称空间和不明确的符号,c++,visual-studio-2010,templates,namespaces,using,C++,Visual Studio 2010,Templates,Namespaces,Using,我有一个涉及嵌套名称空间和模板类的问题。我还能够创建测试用例,它产生与实际代码相同的错误,但可读性更强 使用VS2012和2010平台工具集编译以下代码会导致错误: namespace A { namespace B { namespace C1 { struct SMeasResult{}; } namespace C2 { struct SMeasResult{}; }
namespace A
{
namespace B
{
namespace C1
{
struct SMeasResult{};
}
namespace C2
{
struct SMeasResult{};
}
}
}
namespace C1Test
{
using namespace A::B::C1;
template<typename T>
class Fook
{
public:
void Yu()
{
SMeasResult Field;
}
};
}
namespace C2Test
{
using namespace A::B::C2;
template<typename T>
class Fook
{
public:
void Yu()
{
SMeasResult Field;
}
};
}
void m(){
C1Test::Fook<int> yu;
C2Test::Fook<int> me;
yu.Yu();
me.Yu();
}
名称空间A
{
命名空间B
{
命名空间C1
{
结构SMeasResult{};
}
命名空间C2
{
结构SMeasResult{};
}
}
}
命名空间测试
{
使用名称空间A::B::C1;
模板
福班
{
公众:
余华()
{
SMeasResult字段;
}
};
}
命名空间测试
{
使用名称空间A::B::C2;
模板
福班
{
公众:
余华()
{
SMeasResult字段;
}
};
}
void m(){
C1Test::福佑;
C2Test::福美;
yu.yu();
我;
}
具体误差如下:
1>------ Build started: Project: MultiVicomTest (Visual Studio 2010), Configuration: Debug Win32 ------
1> test.cpp
1>c:\code\test.cpp(27): warning C4101: 'Field' : unreferenced local variable
1> c:\code\test.cpp(26) : while compiling class template member function 'void C1Test::Fook<T>::Yu(void)'
1> with
1> [
1> T=int
1> ]
1> c:\code\test.cpp(49) : see reference to class template instantiation 'C1Test::Fook<T>' being compiled
1> with
1> [
1> T=int
1> ]
1>c:\code\test.cpp(43): error C2872: 'SMeasResult' : ambiguous symbol
1> could be 'c:\code\test.cpp(11) : A::B::C2::SMeasResult'
1> or 'c:\code\test.cpp(7) : A::B::C1::SMeasResult'
1> c:\code\test.cpp(42) : while compiling class template member function 'void C2Test::Fook<T>::Yu(void)'
1> with
1> [
1> T=int
1> ]
1> c:\code\test.cpp(50) : see reference to class template instantiation 'C2Test::Fook<T>' being compiled
1> with
1> [
1> T=int
1> ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
1>----构建已启动:项目:MultiVicomTest(Visual Studio 2010),配置:调试Win32------
1> test.cpp
1> c:\code\test.cpp(27):警告C4101:“字段”:未引用的局部变量
1> c:\code\test.cpp(26):编译类模板成员函数“void C1Test::Fook::Yu(void)”时
1> 与
1> [
1> T=int
1> ]
1> c:\code\test.cpp(49):请参阅对正在编译的类模板实例化“C1Test::Fook”的引用
1> 与
1> [
1> T=int
1> ]
1> c:\code\test.cpp(43):错误C2872:“SMeasResult”:符号不明确
1> 可以是“c:\code\test.cpp(11):A::B::C2::SMeasResult”
1> 或“c:\code\test.cpp(7):A::B::C1::SMeasResult”
1> c:\code\test.cpp(42):编译类模板成员函数“void C2Test::Fook::Yu(void)”时
1> 与
1> [
1> T=int
1> ]
1> c:\code\test.cpp(50):请参阅对正在编译的类模板实例化“C2Test::Fook”的引用
1> 与
1> [
1> T=int
1> ]
======生成:0成功,1失败,0最新,0跳过==========
我不明白为什么“SMeasResult”符号对编译器来说是模糊的,因为它是在一个单独的名称空间中使用的。
到目前为止,我能发现的是,只有当类是模板化类时,才会出现这个问题。删除模板定义时不会出现相同的问题
有人能告诉我我是否做错了什么吗?在我看来,这实际上像是一个编译器错误。当您考虑编译的<代码> C1Test< /Cord>版本没有模糊的函数时,我怀疑在<代码>命名空间C1Test中使用的命名空间甚至连在<代码> C2Test< /Cord>命名空间中仍然存在。 g++4.4和4.5都可以很好地编译这段代码,这进一步证实了这一点 使用A::B::C1::SMeasResult; 及 使用A::B::C2::SMeasResult; 在C1Test和C2Test命名空间中。这就解决了问题 顺便说一句
为什么需要这么多名称空间?STL非常大,但它只使用了一个名称空间-std.我敢肯定这是一个bug。Gcc和clang编译得很好,我也不明白为什么会有歧义。自C++98以来,MSVC从未按照语言标准的要求对模板中使用的名称实施过两阶段查找。这个bug很可能就是它的结果。是的,使用是在visual上泄漏的,而不是在g++中。因为我不太喜欢这个关键字,我不知道标准是怎么说的。有趣的是,在
C1Test
之前用命名空间C2Test
对代码重新排序会导致SMeasResult
内部C2Test
仍然报告“歧义”。事实上,C1
中的声明出现在C2
之前似乎比使用顺序更重要。我的错误是——重要的是模板实例化的顺序,而不是任何声明。无论C1
、C2
、C1Test
或C2Test
的声明顺序如何,要实例化的第二个模板都会因错误而受到“谴责”。感谢您在g++上测试此功能。起初,我担心标准中没有完全规定这种情况,但似乎应该归咎于VS编译器。不幸的是,由于遗留代码和对其他库的依赖,我们无法使用其他编译器。我想我们必须通过完全指定这些模板定义中的符号来解决这个问题,直到编译器团队能够解决这个问题。Boost也很大,它使用了大量的名称空间;)在这个特定的例子中,我们有一个大型的代码库,其中包含与不同种类的无线电技术相关的代码。我们希望将相应的类移动到与它们所代表的技术相似的名称空间中,因此需要许多名称空间。由于还集成了许多其他平台(.NET、Java),我们选择了一种与之类似的方式(想想这些平台中的大量名称空间)。