Как конструктор копирования может быть вызван с помощью rvalue - PullRequest
0 голосов
/ 04 июля 2018

MWE:

struct A {
    A() {std::cout << "constructor" << std::endl; }
    A(const A& a) {std::cout << "copy constructor" << std::endl; }
    A(A&& a) {std::cout << "move constructor" << std::endl; }
};

int main() {
    A a1{};
    A a2{ a1 };
    A a3{ A{} };
    A a4{ std::move(a3) };
    return 0;
}

Выход:

constructor
copy constructor
constructor
move constructor

для a2 copy elision используется, что является оптимизацией компилятора, и все вроде бы хорошо. Однако, когда я закомментирую конструктор перемещения, вместо конструктора перемещения вызывается конструктор копирования. Как можно преобразовать rvalue в ссылку на const lvalue? Выход:

constructor
copy constructor
constructor
copy constructor

Программа скомпилирована в VS2017.

1 Ответ

0 голосов
/ 04 июля 2018

от en.cppreference.com:

Если предусмотрены конструкторы копирования и перемещения, а другие нет конструкторы жизнеспособны, разрешение перегрузки выбирает ход конструктор, если аргумент является rvalue того же типа (xvalue такой как результат std :: move или prvalue, такой как безымянный временно (до C ++ 17)) и выбирает конструктор копирования, если Аргументом является lvalue (именованный объект или функция / оператор, возвращающий lvalue ссылка). Если предоставляется только конструктор копирования, все категории аргументов выбирают его (если требуется ссылка на const, так как rvalues ​​может связываться с ссылками const), что делает копирование запасного варианта для перемещения, когда перемещение недоступно.

Это ясно говорит о том, что rvalue может быть привязано к ссылке на постоянное значение.

...