Если вы никогда больше не ссылаетесь на эту переменную, разрешено ли компилятору переместить ее в результирующий объект функции?
Нет.Единственной ситуацией, когда компилятору разрешено заменять копию ходом, являются те же самые ситуации, когда ему разрешено выполнять удаление копии.Эти ситуации включают в себя возврат локального объекта по значению или инициализацию объекта временным.В этих случаях компилятору разрешается исключить копию, создавая источник и нацеливаясь на один и тот же объект.Если компилятор не может сделать это по какой-либо причине, он должен рассматривать исходный объект как значение по отношению к разрешению перегрузки для выбора соответствующего конструктора для целевого объекта.В вашем случае, однако, файл является Lvalue, и ни один из вышеперечисленных случаев не применяется.Вам придется использовать явное перемещение.
К сожалению, в C ++ 11 нет синтаксиса для «захвата хода».ИМХО, это позор.Но std :: bind поддерживает это.Должна быть возможность комбинировать std :: bind с лямбда-выражением, например:
void foo(char const* p) {
string s = p;
auto fun = bind([](string const& s){
...
},move(s));
fun();
}
, чтобы строка была перемещена в объект функции.
Если вы намереваетесь вызвать эту функциютолько один раз и хотите снова вывести строку из объекта функции, вы можете использовать неконстантную ссылку:
void foo(char const* p) {
string s = p;
auto fun = bind([](string & s) {
some_other_func(move(s));
},move(s));
fun();
}
Обратите внимание, что если вы не хотите использовать здесь привязку, но разрешите лямбдуконструктор объекта создает копию s, перемещение строки из объекта функции требует ключевого слова mutable:
void foo(char const* p) {
string s = p;
auto fun = [=]() mutable {
// ^^^^^^^
some_other_func(move(s));
};
fun();
}
, потому что в противном случае функция operator () типа замыкания будет квалифицирована как const, что, в свою очередь, составляет s
константно-квалифицированная строка.
В C ++ 14 предложение захвата лямбды стало немного более гибким.Теперь мы можем написать
void foo(char const* p) {
string s = p;
auto fun = [s=move(s)]() mutable { // #1
some_other_func(move(s)); // #2
};
fun();
}
, где # 1 перемещает строковое значение в лямбда-объект, а # 2 перемещает строковое значение наружу (в зависимости от того, как some_other_func
объявлено точно).