Как std::move может работать с конструктором копирования, который принимает неконстантную ссылку?

Я читал о std::move. Основываясь на довольно немногих материалах, я пришел к выводу, что std:: move - это просто функция, которая преобразует тип своего аргумента в ссылку-значение.

Я также читал, что rvalue-ссылки могут использоваться с функциями, которые принимают свои аргументы в качестве const-ссылок. Это имеет смысл, поскольку содержимое объектов гарантированно не будет изменено.

Чтобы проверить эти идеи, я провел очень простой эксперимент с классом, расположенным ниже.

Я создал объект t1 и использовал std:: move для преобразования его в rvalue-reference и попытался создать еще один объект t2 с вызовом copy-constructor.

Загадочная часть заключается в том, что даже если я не предоставлю move-constructor, он будет работать с copy-constructor, который я намеренно определил его параметром как неконстантную ссылку.

Однако, если std:: move преобразует тип t1 в rvalue-reference, как компилятор может связать его с lvalue-reference?

Кстати, я использую "Microsoft (R) Microsoft Visual Studio 2012 версии 11.0.50727.1".

Не могли бы вы объяснить, что мне здесь не хватает?

Большое спасибо.

#include <iostream>
#include <algorithm>

using namespace std;

class Trace {
    public:
        Trace() {
        }

        // @1
        Trace(Trace& t) {
            cout << "trace::trace(&)" << endl;
        }

        // @2
        Trace(Trace&& t) {
            cout << "trace::trace(&&)" << endl;
        }
};

int main(int argc, const char *argv[])
{
    Trace t1;

    // Calls @2 if it exists, otherwise calls @1 
    Trace t2(std::move(t1));
    return 0;
}

0 ответов

Другие вопросы по тегам