8

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

使用 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();
}

具体错误如下:

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 ==========

我不明白为什么符号“SMeasResult”对编译器来说是模棱两可的,因为它是在单独的命名空间中使用的。到目前为止我能发现的是,这个问题只在类是模板类时出现。删除模板定义时不会出现同样的问题。

如果我做错了什么,谁能告诉我?

4

2 回答 2

3

这对我来说实际上看起来像一个编译器错误。当您考虑C1Test编译的函数版本没有歧义时,我怀疑其中的 using 命名空间会以某种方式namespace C1Test持续到C2Test命名空间中。

g++ 4.4 和 4.5 都可以很好地编译此代码这一事实进一步证实了这一点。

于 2013-08-08T14:55:54.620 回答
0

尝试使用 A::B::C1::SMeasResult; 并使用 A::B::C2::SMeasResult; 在您的 C1Test 和 C2Test 命名空间中。这解决了这个问题。

BTW 为什么需要这么多命名空间?STL 非常大,但它只使用 1 个命名空间——std。

于 2013-08-08T15:05:18.517 回答