c++ - 无需递归调用一个对象上每个元组元素的函数

标签 c++ tuples c++14 variadic-templates

我有一个 A 类的对象,它可以用不同的类型调用,并在每次调用时返回更改后的自身。对于这个问题,A 会做

struct A {
    A call(const int&) {
    }
    A call(const string& s) {
    }
    ////
} a;

所以我有一个未知类型的元组:

std::tuple<Types...> t;

我想用每个元组元素调用 a,所以我想得到类似的东西:

b = a;
b = b.call(get<0>(t));
b = b.call(get<1>(t));
b = b.call(get<2>(t));
//...

b = a.call(get<0>(t)).call(get<1>(t)).call(get<2>(t)...)

顺序并不是很重要(我的意思是如果调用顺序颠倒甚至打乱也没关系)。

我知道递归是可行的,但它很丑陋。不递归是否可以实现?

最佳答案

您可以使用 std::index_sequence<Is...> ,类似于:

namespace detail
{

    template <std::size_t...Is, typename T>
    void a_call(A& a, std::index_sequence<Is...>, const T& t)
    {
        int dummy[] = {0, ((a = a.call(std::get<Is>(t))), void(), 0)...};
        static_cast<void>(dummy); // Avoid warning for unused variable.
    }

}

template <typename ... Ts>
void a_call(A& a, const std::tuple<Ts...>& t)
{
    detail::a_call(a, std::index_sequence_for<Ts...>{}, t);
}

在 C++17 中,折叠表达式允许:

    template <std::size_t...Is, typename T>
    void a_call(A& a, std::index_sequence<Is...>, const T& t)
    {
        (static_cast<void>(a = a.call(std::get<Is>(t))), ...);
    }

甚至,使用 std::apply :

template <typename ... Ts>
void a_call(A& a, const std::tuple<Ts...>& t)
{
    std::apply([&](const auto&... args){ (static_cast<void>(a = a.call(args)), ...); }, t);
}

关于c++ - 无需递归调用一个对象上每个元组元素的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32460653/

相关文章:

c++ - 闭包默认捕获开销

boost - std::lock/std::try_lock 是否有 try_lock_for 和 try_lock_until 的模拟?

c++ - Select() 有时不等待

c++ - 仅当在 Visual Studio 之外运行 EXE 时才会出现发布错误

c++ - 在 Compact 7 中使用 wlantool.exe 连接到 wifi 网络失败,错误代码为 1814

c++ - 无法在没有显式范围的情况下访问模板基类的静态成员

F# 元组常量从不初始化

swift - Swift 元组

python - 我正在尝试创建一个 cal_average 函数,但是我不断收到 python 无法分配给函数调用的语法错误

c++ - C++14 中纯右值的 Cv 限定