假设我们有以下函数模板:
template <typename Functor, typename... Arguments>
void IterateThrough(Functor functor, Arguments&&... arguments)
{
// apply functor to all arguments
}
这个函数通常实现如下:
template <typename Functor, typename... Arguments>
void IterateThrough1(Functor functor, Arguments&&... arguments)
{
int iterate[]{0, (functor(std::forward<Arguments>(arguments)), void(), 0)...};
static_cast<void>(iterate);
}
另一种方式:
struct Iterate
{
template <typename... Arguments>
Iterate(Arguments&&... arguments)
{
}
};
template <typename Functor, typename... Arguments>
void IterateThrough2(Functor functor, Arguments&&... arguments)
{
Iterate{(functor(std::forward<Arguments>(arguments)), void(), 0)...};
}
我发现了另一种使用可变 lambda 的方法:
template <typename Functor, typename... Arguments>
void IterateThrough3(Functor functor, Arguments&&... arguments)
{
[](...){}((functor(std::forward<Arguments>(arguments)), void(), 0)...);
}
与前两种方法相比,这种方法有什么优缺点?
最佳答案
对 functor
的调用现在是无序的。编译器可以按照它想要的任何顺序使用您的扩展参数调用 functor
。例如,IterateThrough3(functor, 1, 2)
可以执行 functor(1); functor(2);
或者它可以做 functor(2); functor(1);
,而另外两个总是执行 functor(1);仿函数(2);
.
标准的第 8.5.4/4 节要求从左到右计算 {}
初始化程序中的任何表达式。
Within the initializer-list of a braced-init-list, the initializer-clauses, including any that result from pack expansions (14.5.3), are evaluated in the order in which they appear.
第 5.2.2/4 节指出函数调用的参数可以按任何顺序求值。
When a function is called, each parameter (8.3.5) shall be initialized (8.5, 12.8, 12.1) with its corresponding argument. [Note: Such initializations are indeterminately sequenced with respect to each other (1.9) — end note ]
这可能没有涵盖求值顺序的措辞(我找不到 ATM),但众所周知,函数的参数是按未指定的顺序求值的。编辑:有关标准报价,请参阅@dyp 的评论。
关于c++ - 使用可变参数 lambda 迭代可变参数函数模板的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24289069/