cig*_*ien 15 c++ templates language-lawyer non-type variadic-templates
考虑以下结构:S是一个带有模板类型参数可变参数包的类模板...Ts。该类包含一个嵌套的类模板N,该模板具有单个模板模板参数C。C本身使用一组具有完全类型的非类型模板参数的可变参数包进行模板化Ts...。
template <typename ...Ts>
struct S
{
template <template <Ts...> typename C>
struct N
{
C<42> c;
};
};
Run Code Online (Sandbox Code Playgroud)
GCC 拒绝以下声明c:
error: expansion pattern '<anonymous>' contains no parameter packs
C<42> c;
^
Run Code Online (Sandbox Code Playgroud)
我不知道这个诊断意味着什么,我猜这是一个 GCC 错误。
Clang 接受这种结构,也接受合理的实例化,例如:
template<int> struct W {};
S<int>::N<W> w; // ok, makes sense
Run Code Online (Sandbox Code Playgroud)
当然,声明C<42> c;本身对用作 parameter 的参数的模板施加了限制,C即使Ts...inC只是,这也是必需的auto...。例如, 的第一个参数Ts...必须是可以从 隐式转换的类型int。此外, 中的其余参数Ts...(如果有)必须具有默认值。
template<bool(*)()> struct X1 {};
S<int>::N<X1> x1; // error: value of type 'int' is not implicitly convertible to 'bool (*)()'
template<int, char> struct X2 {};
S<int>::N<X2> x2; // error: too few template arguments for class template 'X2'
Run Code Online (Sandbox Code Playgroud)
有趣的是,...Ts和之间的关系似乎确实存在约束Ts...。例如,所有指定的参数S现在必须是有效的非类型模板参数类型:
template<int> struct Y {};
S<int, void>::N<Y> y; // error: a non-type template parameter cannot have type 'void'
Run Code Online (Sandbox Code Playgroud)
另一方面,Clang 也接受带有看似不兼容的参数的实例化S,以及非类型模板参数C:
template<int> struct Z {};
S<bool(*)(), bool>::N<Z> z; // ok ?? But why? both number and type of 'Ts' is different
Run Code Online (Sandbox Code Playgroud)
这是一个演示。
那么在这种结构中如何...Ts和Ts...相互约束的规则是什么?
我碰到这个问题,而试图理解这个问题,在那里它表明MSVC不接受代码。