2017-02-09 3 views
5

dies wird nicht kompiliert (Android Studio mit NDK und clang) mit einem "call to deleted constructor of c" fehler. Ich weiß, dass ich z. Verwenden Sie eine std::vector und emplace_back(), um ein Element direkt im Container zu konstruieren, aber in meinem Code möchte ich nur Container mit fester Größe und nicht kopierbare/bewegliche Objekte zur Optimierung verwenden. Vermutlich vermisse ich hier etwas Grundlegendes, aber gibt es keine Möglichkeit, das std::array zu initialisieren, ohne zuerst die einzelnen Elemente konstruieren zu müssen und sie dann dorthin zu kopieren?initialisieren std :: array ohne kopieren/verschieben von elementen

+2

Durch die Art und Weise Sie nicht brauchen diese Unterstrichen in Ihren Parameternamen zu setzen. 'C (std :: Zeichenkette a, Std :: Zeichenkette b, Std :: Zeichenkette c): a {a}, b {b}, c {c} {}' hat keine Ambiguitätsprobleme und tut, was Sie erwarten. – nwp

Antwort

6

können Sie Klammer eingeschlossen initializers anstelle von temporären c Objekte verwenden:

std::array<c,2> array = {{{"",""},{"",""}}}; 

oder

std::array<c,2> array{{{"",""},{"",""}}}; 
+0

Ist es eine tragbare Lösung? Ich meine, es hängt davon ab, wie std :: array implementiert ist, es muss genau ein Element vom Typ 'T [N]' enthalten. – marcinj

+0

@marcinj Ich bin mir ziemlich sicher. Das letzte Mal, als ich die Anforderung überprüft habe, war nicht, dass 'std :: array' genau ein Element vom Typ' T [N] 'enthält, sondern dass es sich so verhält, als ob es das getan hätte. Es gab eine ganze Frage darüber, ob das mittlere '{}' weggelassen werden könnte, d. H. Ob dies auch gültig sein sollte: '{{" ""} {{"}" {}}}. Diese letzte Sache könnte sich seit C++ 11 geändert haben. – juanchopanza

+0

Ich frage, weil ich eine SO gelesen habe, wo T.C. sagte, dass es nicht garantiert ist: http://stackoverflow.com/questions/27669200/how-should-i-brace-initialize-an-stdarray-of-stdpairs#comment43754338_27669457. – marcinj

5

Es wäre seit 17 ++ C möglich geworden, aus, dass bei einigen bestimmten Fällen copy elision garantiert .

Unter den folgenden Umständen werden die Compiler erforderlich die Kopier- und Bewe- Konstrukteuren der Klasse wegzulassen Objekte auch wenn kopieren/verschieben Konstruktor und der Destruktor haben beobachtbare Nebenwirkungen:

  • Wenn der Initialisierungsausdruck in der Initialisierung ein Prvalue ist und die cv-unqualifizierte Version des Quelltyps dieselbe Klasse wie die Klasse des Ziels ist, wird der Initialisierungsausdruck verwendet, um das Zielobjekt zu initialisieren:

    T x = T(T(T())); // only one call to default constructor of T, to initialize x 
    

Und für diese Fälle, Kopieren/Verschieben Konstruktor ist nicht zugänglich sein erforderlich.

When copy-elision takes place (until C++17)In those cases where copy-elision is not guaranteed, if it takes place (since C++17) und die Kopier-/move-Konstruktor nicht aufgerufen wird, es muss vorhanden sein und zugänglich (als ob keine Optimierung überhaupt passiert ist), da sonst das Programm schlecht ausgebildet.

LIVE

Verwandte Themen