В нескольких местах я видел рекомендуемые сигнатуры конструкторов копирования и перемещения, указанные как:
struct T
{
T();
T(const T& other);
T(T&& other);
};
Где конструктор копирования принимает константную ссылку, а конструктор перемещения принимает неконстантное значение rvalue ссылка.
Однако, насколько я понимаю, это не позволяет мне использовать семантику перемещения при возврате константных объектов из функции, как в случае ниже:
T generate_t()
{
const T t;
return t;
}
Тестирование с помощью VC11 Beta, T
вызывается конструктор копирования, а не конструктор перемещения. Даже при использовании return std::move(t);
конструктор копирования все равно вызывается.
Я вижу, как это имеет смысл, поскольку t
является константой, поэтому не должно связываться с T&&
. Использование const T&&
в сигнатуре конструктора перемещения работает нормально и имеет смысл, но тогда у вас возникает проблема: поскольку other
является константой, вы не можете обнулить его члены, если они нужны для обнуления - это будет работать только тогда, когда все члены являются скалярами или имеют конструкторы перемещения с правильной подписью.
Похоже, что единственный способ убедиться, что конструктор перемещения вызывается в общем случае, сделать t
неконстантным в первую очередь, но мне не нравится делать это - константные вещи это хорошая форма, и я не ожидал, что клиент T
узнает, что ему пришлось пойти против этой формы, чтобы повысить производительность.
Итак, я думаю, мой вопрос двоякий; во-первых, должен ли конструктор перемещения принимать константную или неконстантную ссылку на rvalue? И второе: прав ли я в этой цепочке рассуждений? Что я должен перестать возвращать константные вещи?