1

шаг У меня есть класс шаблона с VARIADIC конструктором шаблона:VARIADIC конструктор шаблонов и конструктор

template<typename T, int nb = 1> 
class MyClass 
{ 
/* ... some stuff here ... */ 

    template<typename... Ts> 
    MyClass(Ts... ts) 
    { 
     /* ... some code ... */ 
    } 

} 

Как определить конструктор перемещения

MyClass(MyClass&& source) 

Для не шаблонных конструкторов то, что я обычно делаю : построить объект tmp типа MyClass, для которого я std::swap каждый член с *this, а затем я заменяю каждый элемент source на *this*. Теперь tmp содержит весь мусор *this* имел, и я просто пусть сфера моего конструктора заботиться о удаляемого tmp ...

Но здесь я застрял и не знаю, как построить мой MyClass tmp(???) объект.

+2

Easy, вы были почти там: 'MyClass (MyClass && source)/* ... еще несколько вещей здесь ... * /' –

+1

В чем проблема? Что имеет конструктор переменных с конструктором перемещения? – 101010

+0

Как создать объект 'tmp'? Я не уверен, сколько аргументов я должен поставить там ... должен ли я просто вызвать вручную соответствующий конструктор в зависимости от внутреннего состояния 'source'? Как я могу вызвать конструктор для построения tmp, сколько аргументов, какого типа? – MCF

ответ

0

Проблема в том, что аргумент Ts&&... может соответствовать MyClass<T,nb>& (то есть не const). Это делает его лучшим совпадением в случае auto b = a; и аналогичным (потому что a не const).

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

#include <memory> 
#include <string> 
#include <iostream> 

template<typename T, int nb = 1> 
class MyClass 
{ 
    /* ... some stuff here ... */ 

public: 
    template<typename... Ts> 
    MyClass(Ts&&... ts) 
    : _pstr(std::make_shared<std::string>(std::forward<Ts>(ts)...)) 
    { 
    } 

    // match the specific case, and force a copy 
    MyClass(MyClass<T, nb>& r) 
    : MyClass(static_cast<const MyClass<T, nb>&>(r)) 
    {} 

    // and now we must match all copy/move operations   
    MyClass(const MyClass<T, nb>&) = default; 
    MyClass& operator=(const MyClass<T, nb>&) = default; 
    MyClass(MyClass<T, nb>&&) = default; 
    MyClass& operator=(MyClass<T, nb>&&) = default; 

    void print() const { 
     std::cout << *_pstr << std::endl; 
    } 
private: 
    std::shared_ptr<std::string> _pstr; 

}; 

// test 
int main() 
{ 
    auto a = MyClass<int>("hello, world"); 
    auto b = a; 
    auto c = MyClass<int>("goodbye"); 
    auto d = c; 
    b = c; 
    a.print(); 
    b.print(); 
    c.print(); 
    d.print(); 
} 

ожидается выход:

hello, world 
goodbye 
goodbye 
goodbye 
Смежные вопросы