Jar*_*d42 8 c++ language-lawyer variadic-templates c++-concepts c++20
在可变参数模板参数之前我们可以有可变参数概念吗?
我的意思是,遵循法律:
template <class, std::size_t> concept Any = true;
template <class> struct n_ary;
template <std::size_t... Is>
struct n_ary<std::index_sequence<Is...>>
{
template <Any<Is>... Ls, typename ... Ts>
void operator()(Ls..., Ts...) {}
};
Run Code Online (Sandbox Code Playgroud)
演示(仅 clang 接受)
注意:如果没有 extra Ts,所有编译器都接受Demo。
这可能违反了[temp.param] 第 14 节:
...函数模板的模板参数包后面不应跟另一个模板参数,除非该模板参数可以从函数模板的参数类型列表([dcl.fct])推导出来或具有默认参数( [温度扣除])。...
它包括这个例子:
template<class T1 = int, class T2> class B; // error
// U can be neither deduced from the parameter-type-list nor specified
template<class... T, class... U> void f() { } // error
template<class... T, class U> void g() { } // error
Run Code Online (Sandbox Code Playgroud)
然而,f(T..., U...)编译器目前接受类似的情况,将一个(或两个)参数包视为空。
通过第 5 节中关于类型约束的示例,
template<C3<int>... T> struct s5; // associates (C3<T, int> && ...)
Run Code Online (Sandbox Code Playgroud)
您示例中的语法应该“功能上等效,但不等效”于template<typename... Ls, typename... Ts> requires (Any<Ls,Is> && ...). 扩展规则[temp.variadic]要求Ls和Is具有相同的大小,这就是为什么 gcc 和 MSVC 最终拒绝示例中的调用的原因。有趣的是,如果您使用功能等效的语法,clang 确实会与其他编译器一起拒绝它。