在以下情况中,inject-class-name被视为类模板本身的模板名称:
- 后面是<
- 它用作与模板模板参数
对应的模板参数- 它是友元类模板声明的详细类说明符中的最终标识符。
所以我尝试检查所有3个案例(另外在基础模糊的背景下,虽然我认为这不应该在这里)。
第一种情况似乎很简单。
问题是 - 为什么不注释出示例工作?它们不适用于海湾合作委员会和Clang所以我认为这不是一个实施问题
template <template <class> class> struct A;
template <class T> struct Base {};
template <class T> struct Derived: Base<int>, Base<char>
{
// #1
typename Derived::Base<double> d;
// #2
// using a = A<Base>;
using a = A<Derived::template Base>;
// #3
template<class U1>
friend struct Base;
// template<class U>
// friend struct Derived::template Base;
};
以上规则仅适用于模板本身,而不适用于基础吗?如果是这样,基数的规则是什么,特别是对于最后两个案例?
答案 0 :(得分:2)
此处的相关规则是[temp.local]/4:
查找注入类名([class.member.lookup])的查找在某些情况下可能会导致歧义(例如,如果在多个基类中找到它)。如果找到的所有注入类名称引用同一类模板的特化,并且如果该名称用作模板名称,则引用引用类模板本身而不是它的专业化,并不含糊。 [实施例:
template <class T> struct Base { }; template <class T> struct Derived: Base<int>, Base<char> { typename Derived::Base b; // error: ambiguous typename Derived::Base<double> d; // OK };
- 结束示例]
我认为这意味着这是一个gcc和一个clang bug。在:
using a = A<Base>;
找到的所有注入类名称都引用同一类模板的特化(Base<T>
)和该名称用作模板名称(因为它是模板模板参数的模板参数),所以这应该只是引用类模板本身而不是模棱两可。