2016-11-11 3 views
13

Ich versuche, abhängig vom Typ des Konstruktorargument eine Klasse A wie folgt zu definieren:Mitgliedertyp Variable sollte

template< typename T > 
class A 
{ 
    public: 
    A(T elem) 
     : _elem(elem) 
    {} 

    private: 
    TYPE _elem; // "TYPE" should be either "T" in case "elem" is an r-value or "T&" in case "elem" is an l-value. 
}; 

Hier möchte ich _elem entweder den Typ T haben, falls dass das Argument der Konstruktor elem eine ist r-Wert oder der Typ T& im Fall elem ist ein I-Wert.

Weiß jemand, wie dies implementiert werden kann?

+1

Ich bin nicht klug genug, dies für Sie zu schreiben, aber Sie erreichen dies mit Vorlage * Spezialisierung *. Upvoted, um Aufmerksamkeit zu erregen. – Bathsheba

+0

Ich hatte auch eine Notwendigkeit dafür (beim Schreiben von Ansichtsklassen) ... –

Antwort

12

Bis wir template argument deduction for class templates erhalten, müssen Sie eine Hilfsfunktion für diesen Einsatz:

template <typename T> 
auto make_a (T&& elem) { 
    return A<T>{std::forward<T>(elem)}; 
} 

Diese Weiterleitungs Referenz verwendet, um folgern, ob das Argument ein L-Wert oder R-Wert ist und konstruiert die A durch perfekt Forwarding das Argument. Nehmen wir als Beispiel int, wenn ein lvalue übergeben wird, T wird int&, und wenn ein rvalue übergeben wird, T wird int sein.

Ihre A Vorlage wie folgt aussehen nur sollte:

template< typename T > 
class A 
{ 
    public: 
    A(T elem) 
     : _elem(elem) 
    {} 

    private: 
    T _elem; 
}; 

Sie könnten make_a ein Freund und machen den Konstruktor privat machen, wenn Sie Bau von der Factory-Methode zulassen möchten.

+0

Warum ist std :: move im Konstruktor von A? – themagicalyang

+0

@themagicalyang Whoops, Gewohnheit. – TartanLlama

+0

Wenn ein r-Wert übergeben wird, warum ist T dann "int" und nicht "int &&"? –

Verwandte Themen