У меня возникли трудности с пониманием конструкторов перемещения в C++. Я сделал простой класс с конструктором по умолчанию, конструктором копирования, конструктором перемещения и деструктором. Кроме того, я определил функцию с двумя перегрузками: одна принимает ссылку на этот класс, а другая принимает ссылку rvalue на этот класс. Мой тестовый код ниже.
#include <iostream>
class c {
public:
c() {
std::cout << "default constructor" << std::endl;
}
c(const c& s) {
std::cout << "copy constructor" << std::endl;
}
c(c&& s) {
std::cout << "move constructor" << std::endl;
}
~c() {
std::cout << "destructor" << std::endl;
}
};
void f(c& s) {
std::cout << "passed by reference" << std::endl;
}
void f(c&& s) {
std::cout << "passed by rvalue reference" << std::endl;
}
int main() {
c s1; // line 1
std::cout << "\n";
c s2(s1); // line 2
std::cout << "\n";
c s3(c()); // line 3
std::cout << "\n";
f(s1); // line 4
std::cout << "\n";
f(c()); // line 5
getchar();
return 0;
}
Результат, который я получаю, не такой, как я ожидал. Ниже приведен вывод, который я получаю из этого кода.
default constructor
copy constructor
passed by reference
default constructor
passed by rvalue reference
destructor
Я могу понять вывод всех строк, кроме line 3
. На line 3
, который равен c s3(c());
, c()
является значением r, поэтому я ожидаю, что s3
будет построено перемещением. Но вывод не показывает, что он создан для перемещения. На line 5
я делаю то же самое и передаю rvalue
функции f()
, и она действительно вызывает перегрузку, которая принимает ссылку rvalue
. Я очень смущен и буду признателен за любую информацию по этому поводу.
Изменить: я могу вызвать конструктор перемещения, если выполню c s3(std::move(c()));
, но не передаю ли уже rvalue в s3? Зачем мне std::move
?