2013-09-08 5 views
3

Вот код, у меня есть, в качестве фона:Rvalue ссылки конструктор перегрузки

template<typename... Dummy> 
struct tuple; 

template <typename T, typename... TList> 
struct tuple<T,TList...> 
    :public tuple<TList...> 
{ 
    typedef T value_type; 

    tuple(){} 

    template<typename A,typename... AList> 
    tuple(const A& a,const AList&... args) 
     :tuple<TList...>(args...),element(a) 
    { 
    } 

    template<typename A,typename... AList> 
    tuple(A&& a,AList&&... args) 
     :tuple<TList...>(args...),element(a) 
    { 
    } 

    tuple(const tuple<T,TList...>& a) 
     :tuple<TList...>(a),element(a.element) 
    { 
    } 

    tuple(tuple<T,TList...>&& a) 
     :tuple<TList...>(a),element(a.element) 
    { 
    } 

    static const index_t size=1+tuple<TList...>::size; 
    static const index_t offset=sizeof(tuple<TList...>); 

    tuple_unit<T> element; 
}; 

template<typename T> 
struct tuple<T> 
{ 
    typedef T element_type; 

    tuple(){} 

    template<typename A> 
    tuple(const A& a) 
     :element(a) 
    { 
    } 

    template<typename A> 
    tuple(A&& a) 
     :element(a) 
    {  
    } 

    tuple(const tuple<T>& a) 
     :element(a.element) 
    { 
    } 

    tuple(tuple<T>&& a) 
     :element(a.element) 
    { 
    } 

    static const index_t size=1; 
    static const index_t offset=0; 

    tuple_unit<T> element; 
}; 

Поскольку в C++ 11 мы имеем перемещение семантику, я пытался добавить двигаться конструктор в моем проекте. Но результат не такой, как я ожидал.

Когда я пишу

tuple<int,float,double> a(3,5,7); //Success. Use 3,5,7 to init each element in tuple. 
tuple<int,float,double> b(a); //Call template function,not copy ctor,and it failed. 

Я прочитал this, и это заставило меня думать, что b(a) позвонит template<typename A,typename... AList> tuple(A&& a,AList&&... args) и A& && будут заменены A&, но у меня уже есть конструктор tuple(const tuple<T>& a). Почему компилятор подумает, что конструктор шаблонов лучше, чем конструктор копирования?

Что делать, чтобы решить эту проблему?

+1

возможно дубликат [Шаблон Конструктор преобладает над Normal Copy и Move Constructor?] (Http://stackoverflow.com/questions/14100171/template-constructor-taking-precedence-over-normal-copy-and -Move-конструктор) –

ответ

1

Я действительно не вижу необходимости в том, чтобы сами конструкторы также были шаблонами, см. Ниже. Кроме того, рассмотрите использование 'std :: move' в конструкторе перемещения при инициализации члена tuple.

template<typename... Dummy> 
struct tuple; 

template <typename T, typename... TList> 
struct tuple<T,TList...> 
    :public tuple<TList...> 
{ 
    typedef T value_type; 

    tuple(){} 

    tuple(const T& a,const TList&... args) 
    :tuple<TList...>(args...),element(a) 
    { 
    } 

    tuple(T&& a,TList&&... args) 
    :tuple<TList...>(args...),element(a) 
    { 
    } 

    tuple(const tuple<T,TList...>& a) 
    :tuple<TList...>(a),element(a.element) 
    { 
    } 

    tuple(tuple<T,TList...>&& a) 
    :tuple<TList...>(a),element(a.element) 
    { 
    } 

    static const int size=1+tuple<TList...>::size; 
    static const int offset=sizeof(tuple<TList...>); 

    T element; 
}; 

template<typename T> 
struct tuple<T> 
{ 
    typedef T element_type; 

    tuple(){} 

    tuple(const T& a) 
    :element(a) 
    { 
    } 

    tuple(T&& a) 
    :element(a) 
    {  
    } 

    tuple(const tuple<T>& a) 
    :element(a.element) 
    { 
    } 

    tuple(tuple<T>&& a) 
    :element(a.element) 
    { 
    } 

    static const int size=1; 
    static const int offset=0; 

    T element; 
}; 

int 
main() 
{ 
    tuple<int,float,double> a(3,5,7); //Success. Use 3,5,7 to init each element in tuple. 

    tuple<int,float,double> b(a); //Call template function,not copy ctor,and it failed. 
} 
Смежные вопросы