为什么inject-class-name有时不被视为类模板中的模板名称?

led*_*ter 6 c++ templates c++14 injected-class-name c++17

资源

在以下情况中,inject-class-name被视为类模板本身的模板名称:

  • 接下来是<
  • 它用作与模板模板参数对应的模板参数
  • 它是友元类模板声明的详细类说明符中的最终标识符.

所以我试图检查所有3个案例(另外在基础模糊的背景下,虽然我认为这不应该在这里).

第一种情况似乎很简单.

问题是 - 为什么没有注释出实例?他们不在GCC和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;
};
Run Code Online (Sandbox Code Playgroud)

以上规则仅适用于模板本身,而不适用于基础吗?如果是这样,基数的规则是什么,特别是对于最后两个案例?

Bar*_*rry 2

这里的相关规则是[temp.local]/4

\n\n
\n

在某些情况下(例如,如果在多个基类中找到它),查找注入类名称 ([class.member.lookup]) 的查找可能会导致歧义。如果找到的所有注入类名称都引用同一类模板的特化,并且该名称用作 template -name,则引用引用类模板本身而不是其特化,并且不是模糊的。[\xe2\x80\x89示例:

\n\n
template <class T> struct Base { };\ntemplate <class T> struct Derived: Base<int>, Base<char> {\n  typename Derived::Base b;             // error: ambiguous\n  typename Derived::Base<double> d;     // OK\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

\xe2\x80\x94\xe2\x80\x89结束示例\xe2\x80\x89]

\n
\n\n

我认为这意味着这是一个 gcc 和一个 clang bug。在:

\n\n
using a = A<Base>;\n
Run Code Online (Sandbox Code Playgroud)\n\n

找到的所有注入类名称确实引用了同一类模板 ( Base<T>)的特化,并且该名称用作模板名称(因为它是模板模板参数的模板参数),所以这应该只需引用类模板本身,不要含糊不清。

\n