Сначала: где определены std::move
и std::forward
? Я знаю, что они делают, но я не могу найти доказательства того, что для их включения требуется любой стандартный заголовок. В gcc44 иногда std::move
доступен, а иногда и нет, поэтому полезная директива include будет полезна.
При реализации семантики перемещения источник предположительно остается в состоянии undefined. Должно ли это состояние быть действительным для объекта? Очевидно, что вы должны иметь возможность вызвать деструктор объекта и иметь возможность назначать ему любые средства, которые предоставляет класс. Но должны ли действовать другие операции? Я полагаю, что я спрашиваю: если ваш класс гарантирует определенные инварианты, следует ли вам стремиться к принудительному применению этих инвариантов, когда пользователь сказал, что они больше не заботятся о них?
Далее: когда вы не заботитесь о семантике перемещения, существуют ли какие-либо ограничения, которые могут привести к тому, что неконстантная ссылка будет предпочтительнее ссылки rvalue при работе с параметрами функции? void function(T&);
over void function(T&&);
С точки зрения вызывающего абонента время от времени возможность временных функций иногда бывает полезной, поэтому кажется, что нужно предоставлять эту опцию всякий раз, когда это возможно. И ссылки rvalue сами являются lvalues, поэтому вы не можете непреднамеренно вызвать конструктор move вместо конструктора-копии или что-то в этом роде. Я не вижу недостатка, но я уверен, что есть один.
Что подводит меня к моему последнему вопросу. Вы по-прежнему не можете привязывать временные ссылки к неконстантным ссылкам. Но вы можете связать их с неконстантными ссылками rvalue. И вы можете передать эту ссылку как неконстантную ссылку в другой функции.
void function1(int& r) { r++; }
void function2(int&& r) { function1(r); }
int main() {
function1(5); //bad
function2(5); //good
}
Помимо того, что он ничего не делает, есть ли что-то не так с этим кодом? Моя кишка говорит, конечно, нет, так как изменение ссылок на ссылки - это вся суть их существования. И если переданное значение законно const, компилятор поймает его и кричит на вас. Но, судя по всему, это путаница механизма, который предположительно был создан по какой-то причине, поэтому я просто хотел бы подтвердить, что я не делаю ничего глупого.