6

Der folgende Code kompiliert OK XCode 5.0 verwenden, aber nicht Visual Studio 2013.Wie initialisiert man eine Vektorelementvariable in der Klassendefinition?

#include <vector> 

class VectorInit 
{ 
private: 
    std::vector<int> m_vector{1, 2, 3}; // fails to compile using VS 2013 
}; 

int main() 
{ 
    std::vector<int> vector{1, 2, 3}; 

    VectorInit vectorInit; 

    return 0; 
} 

Dies ist der Fehler, dass Visual Studio-Berichte:

Error 1 error C2664: 'std::vector<int,std::allocator<_Ty>>::vector(std::initializer_list<int>,const std::allocator<_Ty> &)' : cannot convert argument 3 from 'int' to 'const std::allocator<_Ty> &' c:\visual studio 2013\projects\vector-init\main.cpp 6 1 vector-init 

Ich habe ein Beispiel zu finden, wie es nicht geschafft einen Vektor wie diesen in einer Klassendefinition zu initialisieren.

Welcher Compiler ist korrekt?

Wenn die Syntax nicht gültig ist, ist die einzige Option, m_vector in der Konstruktorinitialisiererliste zu initialisieren?

+0

Visual 2013 ist noch nicht richtig mit nicht statischen Member in der Klasseninitialisierung in allen Fällen, aggregiert fehlschlägt, nur zum Beispiel Kopie Konstruktor zu sehen. initializer_list ctor auch. – galop1n

+0

@ galop1n Entschuldigung, ich verstehe Ihren Kommentar nicht ganz. Bitte können Sie klären. – ksl

+0

in der Klassenmitgliedsinitialisierung ist ein C++ 11-Feature, das sein Debüt in VS2013 gibt. Wenn der Member jedoch ein Aggregat ist, ist der Compiler fehlerhaft und versucht stattdessen, einen Kopierkonstruktor zu verwenden. Es ignoriert auch Konstruktoren, die eine Initialisierungsliste verwenden, und versucht, die Parameter nur mit regulären Konstruktoren abzugleichen. – galop1n

Antwort

7

In der Klasse Memberinitialisierungsliste ist eine C++ 11-Funktion sein Debüt in VS2013. Wenn der Member jedoch ein Aggregat ist, ist der Compiler fehlerhaft und versucht stattdessen, einen Kopierkonstruktor zu verwenden. Es ignoriert auch Konstruktoren, die die Initialisiererliste verwenden, und versucht, die Parameter nur mit regulären Konstruktorargumenten abzugleichen.

Eine Problemumgehung, Sie können einen temporären Vektor erstellen und dann mit dieser Syntax bis zu einer ordnungsgemäßen Aktualisierung des Compilers verschieben.

class VectorInit 
{ 
private: 
    std::vector<int> m_vector { std::vector<int>{ 1, 2, 5, 7 } }; 
}; 
+0

Danke. Das hat funktioniert. – ksl

4

Wie ein Vektor-Membervariable in der Klassendefinition (C++ 11)

Was Sie tun, ist richtig zu initialisieren. Es initialisiert das Datenelement mit den Werten 1, 2, 3, wenn Sie eine VectorInit instanziieren.

Wenn Sie jedoch einen anderen Konstruktor benötigt, die () erfordert, dann müssen Sie eine alternative Syntax:

std::vector<int> m_vector = std::vector(5, 42); // five elements set to 42 

Welche Compiler ist richtig?

Die Syntax ist gültig C++, so dass die Nicht-VS-Compiler richtig sind.

Wenn Ihr Compiler nicht diese Art der Initialisierung unterstützen, könnten Sie einen Konstruktor Ihrer Klasse als Behelfslösung hinzufügen:

class VectorInit 
{ 
public: 
    VectorInt() : m_vector{1, 2, 3}{} 
private: 
    std::vector<int> m_vector; 
}; 
+0

Warum nicht privat (ein Vektorkonstruktor nimmt eine Initialisierungsliste)? –

+0

@ DieterLücking Das ist eine andere Option, obwohl sie ein anderes Problem anspricht (wie mein zweites Beispiel). – juanchopanza

+0

@juanchopanza Der VS 2013-Compiler akzeptiert diese Syntax ebenfalls nicht. – ksl

Verwandte Themen