Escolha o modelo com base na seqüência de tempo de execução em C ++

Eu tenho um vetor de atributo que pode conter tipos diferentes:

class base_attribute_vector; // no template args

template<typename T>
class raw_attribute_vector : public base_attribute_vector;

raw_attribute_vector<int> foo;
raw_attribute_vector<std::string> foo;

Com base na entrada em tempo de execução do tipo, gostaria de criar a estrutura de dados apropriada. Pseudo-código:

std::string type("int");
raw_attribute_vector<type> foo;

Obviamente, isso falha. Uma solução fácil, porém feia e insustentável, é uma alternância / encadeamento em tempo de execução se:

base_attribute_vector *foo;
if(type == "int") foo = new raw_attribute_vector<int>;
else if(type == "string") ...

Eu li sobre o polimorfismo em tempo de execução com functores, mas achei bastante complexo para uma tarefa que é conceitualmente fácil.

Qual é a melhor e mais limpa maneira de fazer isso funcionar? Eu brinquei comboost::hana, constatando que, embora eu possa criar um mapeamento de string para tipo, a pesquisa só pode ser feita em tempo de compilação:

auto types = 
hana::make_map(
    hana::make_pair(BOOST_HANA_STRING("int"), hana::type_c<int>),
    hana::make_pair(BOOST_HANA_STRING("string"), hana::type_c<std::string>)
);

Todos os tipos possíveis são conhecidos em tempo de compilação. Todas as sugestões são muito apreciadas. Em uma solução perfeita, eu criaria o mapeamento de nome-> tipo em um único local. Depois, eu usaria assim

std::vector<base_attribute_vector*> foo;

foo.push_back(magic::make_templated<raw_attribute_vector, "int">);
foo.push_back(magic::make_templated<raw_attribute_vector, "std::string">);

foo[0]->insert(123);
foo[1]->insert("bla");

foo[0]->print();
foo[1]->print();

Não é necessário que essa mágica aconteça no momento da compilação. Meu objetivo é ter o código mais legível possível.