Явно выберите назначение копии
В С++ 11, если доступны как копирование, так и перенос, компилятор автоматически выбирает назначение копирования, если аргумент равен lvalue и присваивает переключение, если он является rvalue. Используя std::move
можно явно выбрать назначение перемещения для lvalue. Но как можно явно выбрать назначение копии для rvalue?
Пример кода:
#include <iostream>
class testClass
{
public:
testClass &operator=(const int &other) {
std::cout << "Copy assignment chosen." << std::endl;
return *this;
}
testClass &operator=(int &&other) {
std::cout << "Move assignment chosen." << std::endl;
return *this;
}
};
int main(int argc, char *argv[])
{
int a = 4;
testClass test;
test = a; // Selects copy assignment
test = 3; // Selects move assignment
test = std::move(a); // Selects move assignment
// test = std::copy(3); // <--- This does not work
return 0;
}
Ответы
Ответ 1
Один из возможных способов - написать свою собственную copy
чтобы привязать объект к ссылке lvalue:
template <class T>
constexpr T& copy(T&& t) noexcept
{
return t;
}
И вы можете проверить это так:
test = copy(a);
test = copy(3);
test = copy(std::move(a));
Вы можете поместить эту функцию в свое собственное пространство имен, чтобы сохранить чистоту. Вы также можете выбрать лучшее имя для него.
Чтобы устранить страх перед пожизненной проблемой, рассмотрим некоторые соображения:
- Эта функция
copy
принимает ссылку и немедленно возвращает ту же ссылку. Это означает, что вызывающий абонент отвечает за управление временем жизни. - Срок службы временного объекта сохраняется до конца заявления. Это приводит к тому, что объект остается достаточно длинным, чтобы его передавали в левую сторону
=
.
Ответ 2
Вы можете static_cast
для const int&
:
test = static_cast<const int&>(3);