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