使用std ::应用于可变参数包

时间:2019-02-11 13:21:35

标签: c++ templates c++17 stdapply

我试图创建一个通用类,该通用类接受一堆类型,将它们存储在元组中,并可以对它们应用函数。

到目前为止,我尝试过以下操作:

#include <tuple>
struct Base{
    virtual void base_function() = 0;
};

template<typename ...T>
struct A : public Base{
    std::tuple<T...> as;
    A(T... pack):as(pack...){};
    void base_function(){
        std::apply([](auto t){t.base_function();}, as);
    }
};

struct B : public Base{
    void base_function(){};
};


struct C : public Base{
    void base_function(){};
};

struct D : A<B, C>{
    D():A(B(),C()){};
};

我希望适用于在D上调用base_function时从类B和C的base_function上调用。但是编译器会产生以下错误:

  

错误:没有匹配的函数调用
  '__invoke(A<T>::base_function() [with T = {B, C}]::<lambda(auto:1)>, std::__tuple_element_t<0, std::tuple<B, C> >&, std::__tuple_element_t<1, std::tuple<B, C> >&)'

2 个答案:

答案 0 :(得分:16)

std::apply的第一个参数应该是一个与元组元素数量相同的仿函数,因此在您的情况下是可变参数:

template <typename ...Ts>
struct A : public Base{
    std::tuple<Ts...> as;
    A(Ts... pack) : as(pack...){}

    void base_function(){
        std::apply([](auto&... ts){(ts.base_function(), ...);}, as);
    }
};

答案 1 :(得分:4)

std::apply没有按照您的想法做。它用于将参数元组传递给函数(可调用类型)。换句话说,元组本身没有称为base_function的函数。参见https://en.cppreference.com/w/cpp/utility/apply