Да, вы можете сделать. 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 );
}
}