c++ - 使用可变参数 lambda 迭代可变参数函数模板的参数

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

假设我们有以下函数模板:

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/

相关文章:

c++ - 实现简化的 C++ vector 类拷贝 - 无法编译

C++ 错误,从函数调用类成员

C++ 从以空格分隔的文本文件填充字符串 vector

C++ vector 错误 C2036 : 'int (*)[]' : unknown size

c++ - C++ 中的空 std::shared_ptr 和空 std::shared_ptr 有什么区别?

C++ 11 实现接口(interface)的方法不可用。为什么?

c++ - C++11/14 中的高效文件读取

c++ - 对象的布局

c++ - 如何删除重复项并仅保留列表中的唯一指针?

c++ - 我可以使用成员变量实例化成员类模板吗?