c++ - 模板实例化的范围解析

标签 c++ templates visual-c++ name-lookup

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

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/

相关文章:

c++ - 在每个源文件中包含一个头文件

java - 在 JNI 中连接 C++ istream/ostream 和 Java InputStream/OutputStream

c++ - 与模板模板类一起使用的自定义模板参数绑定(bind)器

c++11 - vs 2015 pro 上没有 C++11?

android - 我可以恢复分配给 ccache(编译器缓存)的内存吗?

c++ - 无法使用 CMake 和 ncurses 进行编译

C++ - 两个成员函数因单个函数调用而异

c++ - 组合多个类模板特化

visual-c++ - Visual Studio : Automatic COM registration with dependant DLLs outside Debug/Release dirs

python - 安装橙色图像分析时