Frage

Ich habe ein Programm, das den Typ eines Vektors einzustellen braucht, als das Programm ausgeführt wird (entsprechend einem Wert in einer Konfigurationsdatei).

Ich habe versucht, dies:

int a = 1

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

test.push_back(3);

Aber das gibt mir:

Error   1   error C2065: 'test' : undeclared identifier

Ich bin nicht ganz sicher, warum, aber ich denke, das liegt daran, dass der Vektor nicht tatsächlich zum Zeitpunkt der Kompilierung entschieden wird, so dass der Compiler nicht mit ihm während der Zusammenstellung der Rest des Codes arbeiten können.

Gibt es eine Möglichkeit, die Art eines Vektors zur Laufzeit zu entscheiden, ähnlich dem, was ich oben versucht haben? Ich habe versucht, eine Version außerhalb der, wenn zu erstellen und löschen Sie ihn dann und neu zu schreiben, um die neue Version in der IF. Das fühlt sich jedoch falsch, und ich kann es sowieso nicht zu arbeiten. Dank.

War es hilfreich?

Lösung

Der Grund, dies nicht der Fall funktioniert, dass Sie die Vektoren in der wenn- sind erklärt und sonst-Block jeweils so gehen sie den Gültigkeitsbereich einmal, dass Block endet.

  

Gibt es eine Möglichkeit, die Art eines Vektors zur Laufzeit ähnlich ist zu entscheiden, was ich oben versucht?

Nein, muss der Typ einer Variablen zum Zeitpunkt der Kompilierung bekannt sein. Ihre einzige Option ist die Linie test.push_back(3) sowie alle folgenden Code zu setzen, die test in die wenn- greift und den anderen Block oder Code-Duplizierung in eine zweite Templat-Funktion zu vermeiden. Dies könnte wie folgt aussehen:

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);
    }
}

Andere Tipps

Der genaue Grund für den Fehler, den Sie bekommen ist ein bisschen eine subtil für einen Anfänger, und es sich um den Umfang der Variablen test, die Sie erstellen. Einfach gesagt, können Sie den Vektor innerhalb der if-Anweisung erstellen, sondern durch die Zeit, die Sie verwenden wollen, gibt es nicht mehr, weil es außerhalb des Gültigkeitsbereichs gegangen ist.

Ich habe Ihren Code mit Klammern umformatiert diesen Effekt bemerkbar zu machen. Beachten Sie, dass meine Version zu Ihrem semantisch äquivalent ist und den gleichen Fehler geben.

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

test.push_back(3);

Wie gesagt, was Sie versuchen, scheint ein wenig seltsam zu tun, und ich muss mich fragen, was Ihr Endziel ist. Das ist nicht zu sagen, dass es nicht Möglichkeiten zu tun, was Sie scheinen wollen, aber ich würde müssen wissen, was Ihre Erfolgskriterien, bevor ich eine geeignetere Methode vorschlagen könnte.

Ich bin mir nicht sicher, warum müssen Sie, aber ich schlage vor, Sie zu versuchen, einen Vektor der Union zu verwenden, um Ihr Problem, so etwas zu lösen

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

oder wahrscheinlich elegantere Weg ist, Auftrieb verwenden :: Variante anstelle der Union. Vielleicht bekommen Sie, wenn Sie uns weitere Informationen über Ihr Problem geben einen viel besseren asnwer.

Viel Glück!

Sie können einen Blick auf boost :: any zu erreichen, etwas ähnliches.

Ein Vektor des Typs einstellen (auch bekannt als Template-Instantiierung ) geschieht immer bei der Kompilierung. Weitere Erläuterungen zu dem Wikipedia-Artikel überprüft Metaprogrammierung .

Wenn Sie wirklich einen polymorphen Typen benötigen, könnten Sie vielleicht einen Blick auf der boost :: nehmen Variante Klasse oder etwas ähnliches;
Damit soll einen Teil des Verhaltens von dynamischen Sprachen innerhalb von C ++ zu imitieren, und ist in der Regel für die Anbindung mit (oder Umsetzung) sie verwendet. Sie könnten einen "Vektor a" und a.push_back (Variant ((unsigned int) erstellen ..). die Konstrukteure für Werte geschoben Zeittyp kompilieren müssen.

Es wäre auch möglich, eine vektorisiert Variantenklasse zu machen, die die Typinformationen für die gesamte Sammlung speichert, wenn Sie die Werte erwarteten homogen sein.

aber, dann ist es viel wahrscheinlicher, Sie das gewünschte Endergebnis ohne einen solchen Mechanismus acheive kann, Ihr Programm Nacharbeiten vielleicht Laufzeit Typprüfungen zu vermeiden (was höchstwahrscheinlich einige der Vorteile der Verwendung von C ++ über eine andere Sprache an erster Stelle negiert ).

Sie könnten die typabhängigen Teile als Vorlagen schreiben (wie oben vorgeschlagen), und wählen Sie einen alternativen Codepfad auf der Konfigurationsdatei Einstellung basiert geprüft und einmal versendet. Diese Art der Codierung wird etwas leichter in C ++ 0x mit ‚auto‘ und decltype () zu.

Der spezielle Fall von unsigned gegen unterzeichneten Werte beinhaltet so dass ein weiteres Bit, das oder den Grenznutzen im Vergleich zu der zusätzlichen Komplexität ungewöhnlich klingt, aber ich kann man sich leicht vorstellen, eine Implementierung zu wollen, die zwischen einfachen und doppelten Genauigkeit Schwimmer zum Beispiel wechseln .

Noch eine weitere einfache Möglichkeit wäre, eine Kompilierung für die Einstellung Typen zu machen (zum Beispiel als eine Definition aus den Build-Einstellungen oder Make-Datei eingeführt), dann mehrere Versionen des Programms verteilen, was Sinn unter bestimmten Umständen machen könnte. Allerdings sind die Vorlagen bereits vorgeschlagen, eher die nützlichste Option sein.

In Ihrem Beispiel haben Sie unabhängige Instanzen einer Variablen test in jedem Zweig der if Anweisung erstellt, von denen jeder sofort den Gültigkeitsbereich verlässt. Also, wenn die Compiler es test.push_back(3); bekommen kein test Variable in Umfang, damit der Fehler auf.

Ihr Problem zu beheben, können Sie die Art System nicht bekämpfen: dass int angenommen und unsigned int sind die tatsächlichen Typen in Frage, die Sie viel besser dran vector<int> durchgängig bei allen sein würde, vorausgesetzt, dass Sie eigentlich nicht die gesamte Bandbreite benötigen ein unsigned int.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top