" typename qualified-id"引用非类型参数声明中的类型

时间:2016-11-05 15:44:22

标签: c++ language-lawyer

  

14.1 [temp.param],第2段

     

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

我对粗体文字的含义有点困惑。具体来说,typename可以出现在两个不同的上下文中( type-specifier template-parameter ),但这是指哪个?

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

    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
    }
    

    但是,A::XB::X都不是非类型参数声明(它们是成员声明)。

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

2 个答案:

答案 0 :(得分:5)

这是关于

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

此处,typename T表示T是命名模板类型参数,但typename T::X是未命名的非类型模板参数的类型。

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

typename T无法在参数声明中解析为 typename-specifier ,因为它缺少 nested-name-specifier ,所以它必须是类型参数

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

我认为没有含糊之处,但文中阐明了这两个模板参数的解析方式有多么不同。

答案 1 :(得分:0)

typename后跟非限定ID命名模板类型参数。typename后跟限定ID表示非type131参数声明中的类型

示例:使用g ++ -std = c ++ 2a

编译
#include<iostream>
using namespace std;

namespace X {
    struct S {
    int i;
    };
}

typename X :: S是限定ID,用于声明非类型模板参数

T是不合格的id,它命名为模板参数

template< typename X::S &N,typename T>
    void fun(T a) {
    cout << "non-type paramet N.i = " << N.i << endl;
    cout << "type paramet a = " << a << endl;
}

X::S  x{ i:10 };
int main() {
    fun<x,int >(5);
}