首页 > 解决方案 > 我们可以在可变参数模板参数之前有可变参数概念吗?

问题描述

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

我的意思是,遵循法律:

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...) {}
};

Demo(只有 clang 接受)

注意:没有 extra Ts,它被所有编译器Demo接受。

标签: c++language-lawyervariadic-templatesc++20c++-concepts

解决方案


这可能违反了[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

但是,f(T..., U...)编译器目前接受类似的情况,它们将一个(或两个)参数包视为空。

通过第 5 节中关于类型约束的示例,

template<C3<int>... T> struct s5;       // associates (C3<T, int> && ...)

您示例中的语法应该与template<typename... Ls, typename... Ts> requires (Any<Ls,Is> && ...). 扩展规则[temp.variadic]要求它Ls具有Is相同的大小,这就是 gcc 和 MSVC 最终拒绝您示例中的调用的原因。有趣的是,如果您使用功能等效的语法,clang 确实会加入其他编译器拒绝它的行列。


推荐阅读