Czy konstruktor ruchów powinien przyjmować stałe lub niestałe odniesienie do wartości rvalue?

W kilku miejscach widziałem zalecane podpisy konstruktorów kopiowania i przenoszenia podane jako:

struct T
{
    T();
    T(const T& other);
    T(T&& other);
};

Gdzie konstruktor kopiowania przyjmuje stałą referencję, a konstruktor ruchu przyjmuje niestałe odniesienie do wartości rvalue.

O ile widzę, to uniemożliwia mi wykorzystanie semantyki ruchu podczas zwracania obiektów const z funkcji, jak w przypadku poniżej:

T generate_t()
{
    const T t;
    return t;
}

Testowanie tego z VC11 Beta,Twywoływany jest konstruktor kopiowania, a nie konstruktor ruchu. Nawet używającreturn std::move(t); konstruktor kopii jest nadal wywoływany.

Widzę, jak to ma sens, ponieważt jest const, więc nie powinien się wiązaćT&&. Za pomocąconst T&& w ruchu podpis konstruktora działa dobrze i ma sens, ale wtedy masz problem, ponieważother jest const, nie można zlikwidować jego członków, jeśli muszą zostać zlikwidowane - będzie działać tylko wtedy, gdy wszyscy członkowie są skalarami lub przenoszą konstruktory z odpowiednim podpisem.

Wygląda to na jedyny sposób, aby upewnić się, że konstruktor ruchu został wywołany w ogólnym przypadku, który ma zostać wykonanyt w pierwszej kolejności non-const, ale nie lubię tego robić - budowanie rzeczy jest dobrą formą i nie oczekiwałbym klientaT wiedzieć, że musieli się przeciwstawić tej formie, aby zwiększyć wydajność.

Myślę więc, że moje pytanie jest dwojakie; po pierwsze, czy konstruktor ruchów powinien przyjmować stałe lub niestałe odniesienie do wartości rvalue? Po drugie: czy mam rację w tej linii rozumowania? Że powinienem przestać zwracać rzeczy, które są stałe?

questionAnswers(4)

yourAnswerToTheQuestion