Использование std :: apply с различными пакетами - PullRequest
0 голосов
/ 11 февраля 2019

Я пытаюсь создать универсальный класс, который принимает пакет типов, сохраняет их в кортеже и может применять к ним функцию.

До сих пор я пробовал следующее:

#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()){};
};

Я ожидал, что вызов будет вызываться для base_function из классов B и C при вызове base_function для D. Но компилятор генерирует следующую ошибку:

ошибка: не соответствует функция для вызова
'__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 голосов
/ 11 февраля 2019

Первый параметр 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);
    }
};
0 голосов
/ 11 февраля 2019

std::apply не делает то, что вы думаете.Он предназначен для передачи набора параметров в функцию (тип Callable).Другими словами, сам кортеж не имеет функции с именем base_function.см https://en.cppreference.com/w/cpp/utility/apply

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...