Можно создать массив различных структур в C ++ - PullRequest
2 голосов
/ 28 апреля 2020

У меня есть такая структура:

struct A { ... };
struct B { ... };

И у меня есть такой шаблон:

template<typename struct_arg>
class X { ... }

Теперь я хочу создать массив аргументов в виде структуры, подобной этой:

args [2] { A, B };

for (args) {
    X<args[i]> x;
}

Можно ли создать такой массив!?

1 Ответ

2 голосов
/ 28 апреля 2020

Да, вы можете сделать. std :: option создан для этого использования, и вы можете получить доступ к таким членам варианта с помощью std :: visit .

Но если вы это сделаете, оставайтесь в Имейте в виду, что каждый элемент массива имеет дополнительный элемент данных, который имеет информацию о типе, и что каждый элемент имеет как минимум размер самого большого типа, который вы храните. А также std::visit идет с накладными расходами, так как должна быть создана таблица для доступа к элементу данных. Обычно это делается во время компиляции, но иногда g ++ генерирует его во время выполнения, что значительно снизит скорость!

struct A
{
    void Do() { std::cout << "A" << std::endl; }
};  

struct B
{
    void Do() { std::cout << "B" << std::endl; }
};  

int main()
{   
    std::array<std::variant< A,B >,2> arr{ A{}, B{}, B{}, A{} };

    for ( auto& element: arr )
    {   
        std::visit( []( auto& vari ) { vari.Do(); }, element );
    }   
}  

Или если вам нравится ваша инкапсуляция с дополнительной структурой / классом, как показано в вашем примере:

struct A
{
    void Do() { std::cout << "A" << std::endl; }
};

struct B
{
    void Do() { std::cout << "B" << std::endl; }
};

template < typename struct_arg >
struct X: public struct_arg{};


int main()
{
    std::array<std::variant< X<A>,X<B> >,2> arr{ X<A>{}, X<B>{} };

    for ( auto& element: arr )
    {
        std::visit( []( auto& vari ) { vari.Do(); }, element );
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...