c++ - 向后可变参数模板

标签 c++ c++11 variadic-templates

我想编写一个模板函数来执行此操作(伪代码):

shift(T& a,T& b,T& c,...,T& y,const T& z) {
  a = b;
  b = c;
  ...
  y = z;
}

我的尝试涉及将可变参数作为第一个参数,如下所示:

template<typename A, typename B>
inline void shift(A& a, const B& b) noexcept {
  a = b;
}
template<typename B, typename C, typename... AA>
inline void shift(AA&... aa, B& b, const C& c) noexcept {
  shift(aa...,b);
  shift(b,c);
}

为什么这行不通?可变参数只能是最后一个参数吗?那有没有办法让最后一个引用常量呢?

我需要一个 const 引用,例如:

double a, b, c;
shift(a,b,c,5);

编辑: 好的,这个特殊问题当然可以通过颠倒函数参数的顺序来解决:

template<typename A, typename B>
inline void shift(const B& b, A& a) noexcept {
  a = b;
}
template<typename C, typename B, typename... AA>
inline void shift(const C& c, B& b, AA&... aa) noexcept {
  shift(b,aa...);
  b = c;
}

但我仍然想知道语法是否允许将可变参数放在最后一个以外的任何地方,以及在什么情况下?

最佳答案

正如 T.C. 下面的评论所指出的,在您的第一个示例中 aa 处于非推导上下文中(14.8.2.5 p5 定义了非推导上下文,包括“一个函数参数包没有出现在参数声明列表的末尾”),因此无法推导出参数包。

if syntax allows for placing variadic arguments in any place other then the last and under what circumstances?

除了上述导致第一个示例出现问题的限制外,模板参数包必须是最后一个模板参数,除非可以推导出所有后续模板参数。 14.1 [温度参数] p11:

A template parameter pack of a function template shall not be followed by another template parameter unless that template parameter can be deduced from the parameter-type-list of the function template or has a default argument (14.8.2).

所以这是可以的,因为两个模板参数包都可以独立于函数参数推导:

template<typename... T, typename... U>
  void f(std::tuple<T...>, std::tuple<U...>)
  { }

另一种编写 shift 函数的方法是使用 index_sequence

#include <tuple>
#include <iostream>

template<typename... T, size_t... I>
void
shift_impl(std::tuple<T...> t, std::index_sequence<I...>)
{
  // Use pack expansion with comma operator to populate unused array:
  int dummy[] = {
    (std::get<I>(t) = std::get<I+1>(t), 0)...
  };
}

template<typename T0, typename... T>
void
shift(T0&& arg0, T&&... args)
{
  shift_impl(std::tie(arg0, args...), std::index_sequence_for<T...>{});
}

int main()
{
  int i = 0, j = 1, k = 2;
  shift(i, j, k);
  std::cout << i << ' ' << j << ' ' << k << '\n';
}

关于c++ - 向后可变参数模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33661847/

相关文章:

C++ 无法将派生类转换为基类

c++ - 如何从以类为模板类型的链表中显示?

c++ - 我应该用 sleep_for 交换 usleep

c++ - 如何将通用错误代码枚举与来自 <system_error> 的 system_category 错误代码一起使用?

c++ - 为什么模板参数解包有时不适用于 std::function?

C++ 可变参数模板和隐式转换

c++ - 该程序的输出是什么?

c++ - 为什么函数中本地定义的结构需要赋值运算符和复制构造函数

c++ - 带有整数参数的 std::pow,与整数类型进行比较

c++ - 可变参数模板和混入的歧义错误