我有以下一组类(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 在 typename
或 template
的使用方面不严格,因为它可以完全推导出符号的性质(将常规变量与函数或类型区分开来), 然而,当一个人的目标是与其他编译器兼容时,这是一场噩梦。
如果可以,请放弃 MSVC。如果你做不到……祝你好运。
关于c++ - 模板实例化的范围解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8226971/