Con*_*tor 7 c++ lambda templates variadic-functions c++11
假设我们有以下函数模板:
template <typename Functor, typename... Arguments>
void IterateThrough(Functor functor, Arguments&&... arguments)
{
// apply functor to all arguments
}
Run Code Online (Sandbox Code Playgroud)
此功能通常如下实现:
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);
}
Run Code Online (Sandbox Code Playgroud)
其他方式:
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)...};
}
Run Code Online (Sandbox Code Playgroud)
我找到了另一种使用可变参数lambda的方法:
template <typename Functor, typename... Arguments>
void IterateThrough3(Functor functor, Arguments&&... arguments)
{
[](...){}((functor(std::forward<Arguments>(arguments)), void(), 0)...);
}
Run Code Online (Sandbox Code Playgroud)
与前两个相比,这种方法有哪些优点和缺点?
呼叫functor现在没有顺序。编译器可以functor按照它想要的任何顺序调用您的扩展参数。举个例子,IterateThrough3(functor, 1, 2)可以做functor(1); functor(2);或它可以做functor(2); functor(1);,而其他两个总是做functor(1); functor(2);。
标准第 8.5.4/4 节要求{}初始化器内的任何表达式都是从左到右计算的。
\n\n\n在花括号初始化列表的初始值设定项列表中,初始值设定项子句(包括任何由 pack\n 扩展 (14.5.3) 生成的子句)按照它们出现的顺序进行计算。
\n
第 5.2.2/4 节指出函数调用的参数可以按任何顺序求值。
\n\n\n\n\n当调用函数时,每个形参 (8.3.5) 应使用其相应的参数进行初始化 (8.5, 12.8, 12.1)。[注意:此类初始化彼此之间的顺序不确定 (1.9) \xe2\x80\x94\n 尾注]
\n
这可能不包括求值顺序的措辞(我找不到 ATM),但众所周知,函数的参数是按未指定的顺序求值的。编辑:请参阅@dyp 的评论以获取相关标准引用。
\n