6

我有以下一组类(对我的真实情况的最小复制):

namespace Parent
{
  class A {};

  namespace Nested
  {
    class A {};
  }

  template <typename T>
  class B
  {
    A myA;
  };
}

我希望该成员Parent::B::myA应该被明确地解析为 type Parent::A。但是,在我的项目的其他地方,我有这个:

namespace Parent
{
  using namespace Nested;

  void foo()
  {
    B<int> myB;
  }
}

在 MSVC 2003 下编译失败:

error C2872: 'A' : ambiguous symbol
        could be 'Test.cpp(5) : Parent::A'
        or       'Test.cpp(9) : Parent::Nested::A'
        Test.cpp(26) : see reference to class template instantiation 'Parent::B<T>' being compiled
        with [ T=int ]

如果我在声明中明确说明,代码将编译B::myA,即Parent::A myA;。但是,代码在gcc-4.3.4下编译。这仅仅是 MSVC 2003 的一个错误,还是我真的应该担心我的模板可能被实例化的范围?

4

1 回答 1

7

这是所有版本的 MSVC 中长期存在的错误。

该问题与 MSVC 中模板中名称查找的错误实现有关。

基本上,MSVC 将等到实例化点执行名称查找,而标准明确指出正确的行为是:

  • 立即(在声明点)对非依赖符号执行名称查找
  • 在依赖符号的实例化时执行名称查找

这种行为允许 MSVC 在使用typenameor方面松懈template,因为它可以完全推断符号性质(将常规变量与函数或类型区分开来),但是当一个目标是与其他编译器兼容时,这是一场噩梦。

如果可以,请放弃 MSVC。如果你不能......祝你好运。

于 2011-11-22T13:10:43.817 回答