【问题标题】:Expand a parameter pack with a counter用计数器展开参数包
【发布时间】:2014-09-25 07:38:51
【问题描述】:

我想将参数包扩展为函数调用,如下所示:

func(get_value(arg)...);

其中 func 和 get_value 是两个函数。问题是 get_value 对评估顺序很敏感,所以我认为一种解决方案是生成这样的东西:

func(get_value(arg0, 0), get_value(arg1, 1), get_value(arg2, 2));

例如,如果有三个参数。有了这个计数器,我就会知道评估顺序。这有办法吗?

或者作为另一种解决方案,有没有办法简单地指定这些调用的评估顺序 get_value with args? (如果是这样,我什至不需要计数器。)

【问题讨论】:

  • 您的意思是您希望从左到右严格评估 get_value 调用,还是只是传递 0、1、2... 就足够了?
  • @T.C.确切地。这就是我想要的。
  • 哪一个?从左到右,还是只传递额外的整数?
  • 要么。如果第一个解决方案不可能,我可以修改我的 get_value 函数以接收 int。
  • 使评估顺序严格从左到右的方法是在 braced-init-list 中解压缩 get_value 调用(例如,将get_value 调用数组或元组的结果,然后使用整数序列技巧)。但是 g++ 有一个 bug 打破了这一点,因此目前采用第二种方法更便于移植。

标签: c++ function c++11 parameter-passing variadic-templates


【解决方案1】:

您可以将参数包“压缩”在一起。所以,像这样,使用来自hereseq 的定义:

template <typename ... Args, int ... N>
void F(Args... args, seq<N...>)
{
func(get_value(args, N)...);
}

template <typename ... Args>
void FHelper(Args&&... args)
{
 F(std::forward<Args>(args)..., typename gens<sizeof...(Args)>::type ());
}

你会打电话给FHelper

get_value 具有固定返回类型的情况下,一个更简单的解决方案是更改 func 以将initializer_list 作为输入并像这样调用它:

func({get_value(args)...});

这保留了调用顺序,因为初始化列表中的逗号是序列点。

【讨论】:

  • @WuZhenwei 我只是为更受限制的情况添加了一个更简单的解决方案,以防万一它适用于您的问题。
  • "这会保留调用顺序,因为初始化列表中的逗号是序列点。"不完全的。 C++11 中没有序列点。列表初始化规则保证严格的从左到右求值,但 g++ 目前在这方面被破坏了。
  • 嗯,看起来“当前”不太正确。显然是几天前发布的 GCC 4.9.1 中的 fixed
猜你喜欢
  • 2016-10-06
  • 2018-03-04
  • 2017-06-22
  • 2017-01-10
  • 2015-06-06
  • 1970-01-01
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
相关资源
最近更新 更多