🧠 C++ Задача для продвинутых: загадка с `std::move` и `const`
❓ Задача: что выведет этот код и почему?
#include <iostream>
#include <string>
#include <utility>
std::string identity(std::string&& s) {
std::cout << "rvalue reference\n";
return std::move(s);
}
std::string identity(const std::string& s) {
std::cout << "const lvalue reference\n";
return s;
}
int main() {
const std::string a = "hello";
std::string b = identity(std::move(a));
std::cout << "Result: " << b << std::endl;
}
🔍 Варианты ответов:
• a)
rvalue reference
• b)
const lvalue reference
• c) Ошибка компиляции
• d) Поведение зависит от компилятора
💡 Разбор:
a
объявлена как const std::string
. Даже после std::move(a)
она остаётся const
, потому что std::move
не снимает константность, он лишь преобразует к rvalue:
std::move(const std::string&) → const std::string&&
Смотрим на перегрузки
identity
:•
identity(std::string&&)
— принимает неконстантный rvalue •
identity(const std::string&)
— принимает константный lvalueconst std::string&&
не подходит к std::string&&
, потому что нельзя привязать rvalue-ссылку к `const`-объекту без соответствия типов.👉 Вызовется вторая функция, с
const std::string&
✅ Ответ: b) const lvalue reference
🧠 Вывод:
std::move
не делает объект мутабельным. Если объект const
, он остаётся const
, и rvalue-перегрузки не срабатывают.📌 Совет: перед использованием
std::move
всегда учитывайте `const`-квалификатор. Он может "сломать" ожидаемую семантику перемещения.
>>Click here to continue<<