在可变参数模板参数之前我们可以有可变参数概念吗?

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

sig*_*gma 0

这可能违反了[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]要求LsIs具有相同的大小,这就是为什么 gcc 和 MSVC 最终拒绝示例中的调用的原因。有趣的是,如果您使用功能等效的语法,clang 确实会与其他编译器一起拒绝它。