2016-11-11 23 views
13

я пытаюсь определить класс A следующим образом:Тип переменной-члена должно зависеть от типа аргумента конструктора в

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. 
}; 

Здесь я хочу _elem иметь либо тип T в случае, когда аргумент конструктора elem является r-значение или тип T& в случае, если elem является l-значением.

Кто-нибудь знает, как это можно реализовать?

+1

Я недостаточно умен, чтобы написать это для вас, но вы достигаете этого, используя шаблон * специализацию *. Направлено на привлечение внимания. – Bathsheba

+0

Мне тоже нужно это делать (при написании классов классов) ... –

ответ

12

Пока мы не получим template argument deduction for class templates, вы должны будете использовать вспомогательную функцию для этого:

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

Это использует ссылку переадресации, чтобы вывести, является ли аргумент именующим или Rvalue и строите A по совершенно экспедиторским Аргумент. Принимая в качестве примера int, если передано lvalue, T будет int&, и если передается rvalue, T будет int.

Ваш A шаблон должен просто выглядеть следующим образом:

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

    private: 
    T _elem; 
}; 

Вы могли бы сделать make_a друга и сделать конструктор приватным, если вы хотите разрешить строительство с заводским способом.

+0

Почему std :: move используется в конструкторе A? – themagicalyang

+0

@themagicalyang Упс, привычка. – TartanLlama

+0

Когда передается значение r, почему T является 'int', а не' int && '? –