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

namespace Parent
{
  class A {};

  namespace Nested
  {
    class A {};
  }

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

我希望成员Parent::B::myA应该明确解析为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的一个错误,还是我真的应该担心可以实例化模板的范围吗?

最佳答案

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

该问题与MSVC中模板中名称查找的不正确实现有关。

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

  • 立即(在声明时)为非相关符号执行名称查找
  • 在实例化相关符号
  • 时执行名称查找

    这种行为使MSVC在typenametemplate的使用上松懈,因为它可以完全推断符号的性质(将常规变量与函数或类型区分开),但是当它旨在与其他编译器兼容时,这是一场噩梦。

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

    关于c++ - 模板实例化的范围解析,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8226971/

    10-12 21:33