2016-07-29 3 views
7

Ich habe eine feste Anzahl von Objekten der Klasse T, die nicht kopierbar und nicht standardkonstruierbar sind. Da die Größe fest ist, möchte ich einen Array-ish Container wie std::array anstelle von unique_ptr oder vector verwenden. Ich möchte die zusätzliche indirekte Ebene vermeiden, wenn ich ihr helfen kann.Wie initialisiert man ein std :: array <T, 2> wobei T nicht kopierbar und nicht standardkonstruierbar ist?

Wie initialisiere ich eine std::array<T, 2>? Die Verwendung von array<T, 2> {T(...), T(...)} führt zu einem Fehler beim Konstruktor für gelöschte Kopien. Die Verwendung von array<T, 2> {move(T(...)), move(T(...))} erzwingt nicht, dass die Array-Elemente den Move-Konstruktor verwenden. Wenn std::array<T, 2> von Natur aus nicht funktioniert, was kann ich sonst noch tun, ohne auf eine zusätzliche Schicht von indirekten oder manuellen Speicherverwaltungstechniken wie Placement-Neu zurückgreifen zu müssen?

+0

mir Klingt wie alle Instanzen von T nur über intelligente Zeiger zugegriffen werden. 'std :: array' von unique/shared ptrs zu T, etc ... –

+0

@SamVarshavchik, Aber Sie können' std :: vector' mit move-only, nicht-standard-konstruierbaren Typen einfach in Ordnung. – chris

+0

Was ich erreichen möchte, kann im Prinzip erreicht werden, wenn auch mit chaotischen und schwer zu lesenden Techniken wie der Platzierung neuer. Ich weiß, dass ein Vektor einfach wäre, aber er gibt mir den zusätzlichen Overhead, den ich habe, um zu vermeiden, dass das In-Prinzip völlig vermeidbar ist. – Syncopated

Antwort

0

Mein Beispiel ist nicht die beste, aber es funktioniert .. Erstellen Sie einfach eine Funktion, dass make_array und haben es die Instanzen für Sie erstellen ..

http://ideone.com/fxAO3t

#include <array> 
#include <iostream> 

class Foo 
{ 
    public: 
     Foo(int) 
     { 

     } 

     Foo(const Foo &) = delete; 

     Foo(Foo &&) 
     { 
      std::cout<<"Moved\n"; 
     } 
}; 

template<class... Type> 
constexpr std::array<typename std::common_type<Type...>::type, sizeof...(Type)> make_array(Type&&... t) 
{ 
    return {std::forward<Type>(t)...}; 
} 

int main() { 
    auto arr = make_array(Foo{1}, Foo{2}); 
    return 0; 
} 

Wie in den Kommentaren darauf hingewiesen, Sie können std::array<Foo, 2> arr = {Foo{1}, Foo{2}} tun.

Ich bemerkte, dass Sie versuchten, move in Ihrem Beitrag. Sind Sie sicher, dass Ihre Klasse moveable ist?

+0

Wenn 'Foo' beweglich ist, brauchen Sie die Funktion nicht. Nur 'std :: array arr {1, 2};' ist ausreichend. – Barry

+0

Ahh du hast Recht. OP versuchte genau das zu tun, was Sie gerade vorgeschlagen hatten. Er/Sie machte 'std :: move (Foo)'. – Brandon

5

Keine Notwendigkeit für zusätzliche Sachen, initialisieren Sie es einfach direkt:

class Foo { 
public: 
    Foo() = delete; 
    Foo(int,char) {} 

    Foo(Foo const &) = delete; 
    Foo & operator = (Foo const &) = delete; 
}; 
std::array<Foo, 2> arr {{ {1, '1'}, {2, '2'} }}; 

DEMO

+0

LOL noch eine Reihe von Klammern ... das habe ich vergessen. +1. – Barry

+0

Es scheint für mich zu arbeiten. Wo kann ich die Bedeutung dieser geschweiften Klammern für das std :: array lernen? – Syncopated

Verwandte Themen