2014-03-24 9 views
8
#include <initializer_list> 
#include <iostream> 

namespace { 

class C { 
public: 
    C(C const &) = delete; 
    C(C &&) = delete; 
    C(int) { 
     std::cout << "int\n"; 
    } 
    C(std::initializer_list<int>) { 
     std::cout << "initializer\n"; 
    } 
}; 

void f(C) { 
} 

// Compiles and prints "initializer" when called 
C g() { return {0}; } 
// Fails to compile 
// C h() { return 0; } 

} // namespace 

int main() { 
    // Compiles and prints "initializer" 
    f({0}); 
    // Fails to compile 
    // f(0); 
} 

Ist es möglich, C, einem nicht-kopierbaren, nicht beweglichen Typ, in einen Funktionsparameter oder Funktionsrückgabewert zu konstruieren, ohne dass den initializer_list-Konstruktor aufrufen?Konstruieren eines nicht-kopierbaren, nicht beweglichen Typ in einen Funktionsparameter ohne initializer_list Konstruktor aufruft

+0

ich keine Möglichkeit, das zu tun, sehen (Dies ist auch ein Problem mit In-Class-Initialisierern: 'struct A {std :: vector x {2};}'. Sie können 'x' nicht initialisieren, um die Größe' 2' zu haben und nicht '= sagen 2', weil der Konstruktor explizit ist. –

+1

Sie übergeben eine Kopie des Objekts eines nicht kopierbaren Typs usw. Warum? Macht keinen Sinn – deviantfan

+1

@deviantfan: Ich versuche, das Objekt direkt an Ort und Stelle zu bauen. –

Antwort

2

Es ist nur möglich, wenn Sie C ändern können, so dass der gewünschte Konstruktor anstelle des Initialisierungslistenkonstruktors ausgewählt werden kann, z. durch das Argument Typ in etwas Verpackung, die nicht umrüstbar auf den Elementtyp der Initialisierer-Liste Konstruktor ist:

#include <initializer_list> 
#include <iostream> 

namespace { 

template<class T> 
struct wrap 
{ 
    T value; 
}; 

class C { 
public: 
    C(C const &) = delete; 
    C(C &&) = delete; 
    C(wrap<int>) { 
     std::cout << "int\n"; 
    } 
    C(std::initializer_list<int>) { 
     std::cout << "initializer\n"; 
    } 
}; 

void f(C) { 
} 

// Compiles and prints "int" when called 
C g() { return {wrap<int>{0}}; } 

} // namespace 

int main() { 
    // Compiles and prints "int" 
    f({wrap<int>{0}}); 
    g(); 
} 

Diese Drucke:

int 
int