Pergunta

Eu tenho um programa que precisa para definir o tipo de um vetor como o programa é executado (de acordo com um valor em um arquivo de configuração).

Eu tentei isso:

int a = 1

if(a == 1)  vector<int> test(6);
else  vector<unsigned int> test(6);

test.push_back(3);

Mas isso me dá:

Error   1   error C2065: 'test' : undeclared identifier

Eu não sou inteiramente certo porque, mas acho que isso é porque o vetor não é realmente decidido em tempo de compilação para que o compilador não pode trabalhar com ele enquanto compilar o resto do código.

Existe uma maneira de decidir o tipo de um vetor em tempo de execução semelhante ao que eu tentei acima? Tentei criar uma versão fora do caso e, em seguida, excluí-lo e re-escrever a nova versão dentro do IF. Este, porém, se sente mal e eu não posso obtê-lo para o trabalho de qualquer maneira. obrigado.

Foi útil?

Solução

O motivo ele não funciona é que você está declarando os vetores dentro do se- e outra bloco, respectivamente, assim saem do escopo, uma vez que as extremidades do bloco.

Existe uma maneira de decidir o tipo de um vetor em tempo de execução semelhante ao que eu tentei acima?

Não, o tipo de uma variável deve ser conhecido em tempo de compilação. Sua única opção é colocar o test.push_back(3) line, bem como qualquer código a seguir que acessa test na se- eo else-bloco, ou para evitar código de duplicação em uma segunda função templated. Esta poderia ser assim:

template <class T>
do_something_with_test(vector<T>& test) {
    test.push_back(3);
    // work with test
}

void foo() {
    int a = 1

    if(a == 1) {
        vector<int> test(6);
        do_something_with_test(test);
    }
    else {
        vector<unsigned int> test(6);
        do_something_with_test(test);
    }
}

Outras dicas

A razão exata para o erro que você está recebendo é uma espécie de sutil para um iniciante, e envolve o alcance da test variável que você está criando. Simplificando, você está criando o interior do vetor da instrução if, mas pelo tempo que você está indo para usá-lo, já não existe porque ele passou fora do escopo.

Eu reformatted seu código com suportes para tornar este efeito mais perceptível. Nota que a minha versão é semanticamente equivalente ao seu e vai dar o mesmo erro.

if(a == 1)
{
  vector<int> test(6);
}
else
{
  vector<unsigned int> test(6);
}

test.push_back(3);

Dito isto, o que você está tentando fazer parece um pouco estranho, e eu tenho que saber o que seu objetivo final é. Isso não quer dizer que não há maneiras de fazer o que você parece querer fazer, mas eu preciso saber o que seus critérios de sucesso antes que eu pudesse sugerir um método mais adequado.

Eu não tenho certeza por que você precisa disso, mas eu sugiro que você tente usar um vetor de união para resolver o seu problema, algo como isto

union DataType
{
    int intVal;
    unsigned uintVal;
}
std::vector<DataType> vec;

Ou provavelmente maneira mais elegante é usar boost :: variante em vez da união. Talvez se você nos dar mais detalhes sobre o problema que você obter uma melhor asnwer muito.

Boa sorte!

Você poderia ter um olhar para boost :: qualquer para conseguir algo similar.

Definir o tipo de um vetor (aka instanciação de modelo ) sempre acontece em tempo de compilação. Para mais verificação de esclarecer o artigo da Wikipedia sobre Template metaprogramming .

Se você realmente precisa de um tipo polimórfico, talvez você poderia dar uma olhada no boost :: classe variante ou algo semelhante;
Este destina-se a imitar alguns do comportamento de linguagens dinâmicas dentro C ++, e é geralmente usado para fazer a interface com a (ou de aplicação) eles. você poderia criar um "vector a", e a.push_back (Variant ((int não assinado) ..). os construtores para valores empurrados necessidade tipo de tempo de compilação.

Além disso, seria possível fazer uma classe variante vetorizado que armazena as informações de tipo para toda a coleção se você esperava que os valores para ser homogênea.

mas, é muito mais provável que você posso conseguir o resultado final desejado, sem um tal mecanismo, refazer o seu programa para tipo cheques evitar tempo de execução talvez (o que seria mais provável negar alguns dos benefícios do uso de C ++ em detrimento de outro idioma, em primeiro lugar ).

Você poderia escrever as partes dependentes do tipo de como modelos (como sugerido acima) e selecione um caminho de código alternativo com base na configuração arquivo de configuração verificada & despachado uma vez. Este estilo de codificação fica um pouco mais fácil em c ++ 0x com 'auto' e decltype () também.

O caso específico de não assinado contra valores assinados envolve permitindo mais um pouco, o que soa incomum, ou de benefício marginal em comparação com a complexidade adicional, mas eu posso facilmente imaginar um querendo uma implementação que pode alternar entre flutuante precisão simples e dupla, por exemplo, .

No entanto, outra opção simples seria fazer um ajuste tempo de compilação para o tipo (por exemplo, introduzido como uma definição das configurações de compilação ou makefile), em seguida, distribuir várias versões do seu programa, que pode fazer sentido em algumas circunstâncias. No entanto, os modelos já sugeridas são mais propensos a ser a opção mais útil.

No seu exemplo, você tiver instâncias independentes de um test variável criada em cada ramo da sua declaração if, cada uma das quais sai do escopo imediatamente. Então, quando o compilador começa a test.push_back(3); não há nenhuma variável test em escopo, daí o erro.

Para resolver o seu problema, você não pode lutar contra o sistema Tipo: assumindo que int e unsigned int são os tipos reais em questão você seria muito melhor fora de usar vector<int> todo, presumindo que você realmente não precisa de toda a gama de um unsigned int.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top