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::X
和B::X
都不是非类型参数声明(它们是成员声明)。
对于后一种情况,我不确定为什么这是必要的。为什么不直接用 qualified-id 写下它的类型?是否需要参数化?
答案 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);
}