在 C++17/20 中迭代元组

Jos*_*shK 3 c++ tuples c++17

有谁知道在 C++17/20 中迭代元组的一种好的、干净的方法?假设我们有一些这样的代码:

class Test
{
    public:
        Test( int x ) : x_(x) {};
        void Go() const { std::cout << "Hi!" << x_ << "\n" ; }
        int x_;
};
int main()
{
    std::tuple tplb{ Test{1} , Test{2} ,  Test{3} };
}
Run Code Online (Sandbox Code Playgroud)

我们如何遍历元组并Go()使用最新的 17/20 功能调用每个元组的方法?

我知道你可以只拥有一个对象的向量,然后它就可以轻松工作。我的目标是能够在不必使用虚函数的情况下拥有一定的多态性。

这个想法是能够在元组中拥有支持相同方法的其他对象类型。如果该方法存在于每个对象中,那么代码将编译和执行而无需使用基类、虚拟对象、虚表等。

有什么办法可以用std::applystd::invoke吗?

Jar*_*d42 7

有什么办法可以用std::applystd::invoke吗?

std::apply 用折叠表达式确实满足需要:

std::tuple tplb{ Test{1} , Test{2} ,  Test{3} };

std::apply([](const auto&... tests){(tests.Go(), ...);}, tplb);
Run Code Online (Sandbox Code Playgroud)

在这里,我们Go()为 的每个类型值调用方法tuple

这个想法是能够在元组中拥有支持相同方法的其他对象类型。如果该方法存在于每个对象中,那么代码将编译和执行而无需使用基类、虚拟对象、虚表等。

所以上述方法有效。它你会根据类型去进一步和调度不同的实现,你可以使用overloaded类从性病::访问的例子

template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

auto f = overloaded {
        [](const Test& test) { test.Go(); },
        [](double d) { std::cout << d << ' '; },
        [](const std::string& s) { std::cout << s << ' '; },
    };
std::apply([&](const auto&... e){ (f(e), ...);}, my_tuple);
Run Code Online (Sandbox Code Playgroud)