"typename qualified-id"指的是非类型参数声明中的类型

b1s*_*sub 2 c++ language-lawyer

14.1 [temp.param],第2段

... typename后跟一个unqualified-id命名一个模板类型参数.typename后跟一个qualified-id表示非类型参数声明中的类型 ...

我对粗体文本的含义有点困惑.具体来说,typename可以出现在两个不同的上下文(类型说明符模板参数)中,但这是指哪一个?

  • 对于前一种情况,我考虑过:

    struct A {
        struct X { };
        int X;
    };
    struct B {
        struct X { };
    };
    template<class T> void f(T t) {
        typename T::X x;    // T can be A or B
    }
    
    Run Code Online (Sandbox Code Playgroud)

    但是,既不是A::X也不B::X是非类型参数声明(它们是成员声明).

  • 对于后一种情况,我不确定为什么这是必要的.为什么不用qualified-id直接写下它的类型呢?参数化是必要的吗?

小智 5

这是关于

struct S { typedef int X; };
template <typename T, typename T::X> void f() { }
int main() { f<S, 1>(); }
Run Code Online (Sandbox Code Playgroud)

这里,typename Tmeans T是命名模板类型参数,但是typename T::X未命名的非类型模板参数的类型.

type-parameter是用于模板类型参数的语法,parameter-declaration是用于模板非类型参数的语法.

typename T无法在参数声明中解析为typename-specifier,因为它缺少nested-name-specifier,因此它必须是type-parameter.

typename T::X无法解析为类型参数,因为它只允许typename关键字后面的单个标识符,因此它必须是参数声明.

我认为没有歧义,但文本阐明了这两个模板参数的解析方式有多么不同.