C ++ - Перемещение объекта класса шаблона variadi c в вектор - PullRequest
0 голосов
/ 06 февраля 2020
class Base
{
public:
    virtual void foo() = 0;
};

class A : public Base
{
public:
    void foo() override { std::cout << "A\n"; }
};

class B : public Base
{
public:
    void foo() override { std::cout << "B\n"; }
};

class Registry
{
public:
    static Registry& instance()
    {
        static Registry s_instance;
        return s_instance;
    }

    void register_foo(Base* foo) 
    { 
        m_vec.emplace_back(foo); 
    }

private:
    std::vector<Base*> m_vec;
};

template<typename ... T>
class Foo : public T...
{
public:
    Foo()
    { 
        Registry::instance().register_foo(this);
    }

    void test() { (T::foo(), ...); }
};

int main()
{
    auto f1 = std::make_unique<Foo<A, B>>();
    auto f2 = std::make_unique<Foo<A>>();

    f1->test();
    f2->test();
}

Как видите, класс Base, класс A и класс B.

A и B наследуются от Base. Class Foo - это шаблонный класс, который имеет шаблон variadi c. Идея состоит в том, чтобы иметь возможность передать класс A и класс B в Foo. Затем этот Foo регистрируется в классе Registry / помещается в вектор.

Проблема заключается в следующем - как вы можете видеть, у меня могут быть и Foo<A>, и Foo<A, B>, или * 1020. *. Как я могу иметь такой вектор, который может принимать все возможные типы Foo?

Ответы [ 2 ]

1 голос
/ 06 февраля 2020

Как насчет простого общего базового класса?

class FooBase {
public:
    virtual ~FooBase() {}

    virtual void test() = 0;
};

template<typename... T>
class Foo : public FooBase, public T...
{
public:
    Foo() { }

    void test() override { (T::foo(), ...); }
};

int main()
{
    auto f1 = std::make_unique<Foo<A, B>>();
    auto f2 = std::make_unique<Foo<A>>();

    std::vector<std::unique_ptr<FooBase>> foos;

    foos.push_back(std::move(f1));
    foos.push_back(std::move(f2));
}
0 голосов
/ 06 февраля 2020

A std::vector содержит один тип объектов. Вы не можете помещать объекты разных типов в один и тот же вектор (а объекты, созданные из шаблона с разными аргументами шаблона: разные типы ).

Один вариант (я бы его не рекомендовал) иметь вектор, содержащий экземпляры std::any) - работает, но громоздко и неэффективно работать. Другим вариантом является вектор указателей на общий базовый класс и использование преимуществ полиморфизма. Третий вариант - просто иметь отдельные векторы для каждого типа объекта.

...