我的第一个代码片段编译并正常工作:
template <class x> struct B1
{
template <class x> struct B2 { int getX() { return(16); } };
template <class x> struct B2<x*> { int getX() { return(20); } };
};
void main(int argc, char* argv[])
{
B1<int>::B2<int> a1;
B1<int>::B2<int*> a2;
printf("a1=%d, a2=%d.\r\n", a1.getX(), a2.getX());
}
请注意,两个模板中模板参数的名称都是x
,这不会让编译器感到困惑。第二个示例因编译器崩溃(MSVC 2008)而失败,即没有给出任何语法错误:
template <class x> struct B1
{
template <class x> struct B2 { int getX() { return(16); } };
template <class x> struct B2<x*>;
};
template <class x> template <class x>
struct B1<x>::B2<x*>
{
int getX() { return(3); }
};
我的问题是不是如何修复此示例,这很明显。
我在标准(C ++ 2003)中查看了访问模板头的参数的规则,我找不到任何相关的东西。也许我错过了什么。
在处理B1<x>
时,编译器是否应该只考虑第一个模板头中的params?更可能的是。然后在处理B2<x>
时,它应该同时考虑两者吗?当B1 / B2的参数本身包含限定标识符并且这些标识符想要访问模板标题的参数时,更复杂的情况尤其有趣。为简单起见,我没有给出完整的例子。
如果有人遇到这个并且可以评论或了解一些artickles /书籍,YouTube视频等,我很乐意听到这个。
更新:我刚刚尝试了以下MSVC:
template <class x> struct B1
{
x qq1;
struct B2
{
int x;
};
};
这可以按预期编译和工作。我还尝试了一个访问内部数据字段x
的exe。这表明MS编译器在内部作用域中实现了隐藏模板参数。对我来说,这是合乎逻辑的,即使这不符合标准。