Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 嵌套的名称空间和不明确的符号_C++_Visual Studio 2010_Templates_Namespaces_Using - Fatal编程技术网

C++ 嵌套的名称空间和不明确的符号

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{}; }

我有一个涉及嵌套名称空间和模板类的问题。我还能够创建测试用例,它产生与实际代码相同的错误,但可读性更强

使用VS2012和2010平台工具集编译以下代码会导致错误:

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),我们选择了一种与之类似的方式(想想这些平台中的大量名称空间)。