【发布时间】:2014-06-18 15:09:03
【问题描述】:
假设我们有以下函数模板:
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)...);
}
与前两种方法相比,这种方法有什么优缺点?
【问题讨论】:
-
您的结构构造函数可以使用省略号而不是参数包。
-
@dyp 你的意思是一个简单的可变参数构造函数吗?但这不会违反您在下面引用的规则吗?
-
我的意思是
Iterate(...) {}。对花括号初始化列表的元素的评估是正确排序的,因此Iterate{((void)functor(arguments), 0)...};的“函数参数评估顺序”参数被否决 -
@dyp 我现在明白了,谢谢。由于
operator void()在类decltype(functor(argument))中可能存在(void)functor(arguments), 0的形式不危险吗? -
[class.conv.fct]/1 "转换函数永远不会用于将(可能是 cv 限定的)对象转换为 [...] 或(可能是 cv 限定的)void 。”所以你可以声明一个,但它不会被使用。我的结论是它不会造成任何麻烦。
标签: c++ templates c++11 lambda variadic-functions