Комментарии 8
Возможно не совсем в тему статьи (хотя и близко), но хочется вспомнить о возврате локальных (временных) объектов по константной ссылке:
Тут нет ни копирования, ни перемещения. Но всё работает корректно, т.к. стандарт говорит:
«binding a temporary object to a const reference extends the lifetime of the temporary to the lifetime of the reference itself.»
Саттер называет такую ссылку «кандитатом на самый важный const»
Code
class MyStruct
{
public:
MyStruct(int value) : _value(value){}
private:
// prevent from copying, assigning or moving
MyStruct(const MyStruct & rhs){}
MyStruct& operator=(const MyStruct&){}
MyStruct(MyStruct&& rval)
{
_value = rval._value;
rval._value = 0;
}
int _value;
};
const MyStruct & foo()
{
return MyStruct(42);
}
int main()
{
auto & s = foo();
return 0;
}
// VS2010, /W3
// warning C4172: returning address of local variable or temporary
Тут нет ни копирования, ни перемещения. Но всё работает корректно, т.к. стандарт говорит:
«binding a temporary object to a const reference extends the lifetime of the temporary to the lifetime of the reference itself.»
Саттер называет такую ссылку «кандитатом на самый важный const»
0
Ваш пример неверен. Обратите внимание: у Саттера объекты возвращаются по значению. В этом случае можно поймать временный объект константной ссылкой, избежав лишнего копирования, и использовать его пока жива ссылка.
Ни в коем случае нельзя возвращать ссылки на локальные объекты из функций. Если Вы добавите немного вывода (output) в деструктор объекта и после получения объекта в функции main(), то убедитесь, что объект уничтожен до того, как Вы попытаетесь его использовать.
Ни в коем случае нельзя возвращать ссылки на локальные объекты из функций. Если Вы добавите немного вывода (output) в деструктор объекта и после получения объекта в функции main(), то убедитесь, что объект уничтожен до того, как Вы попытаетесь его использовать.
+5
Вы, ребята, странные. Конечно, объект будет скопирован, потому что перемещающий конструктор не подходит по сигнатуре. Сделайте константную r-value ссылку и будет вам перемещение константных объектов. Другой вопрос — зачем
ideone.com/JaVjwe
struct s1
{
s1() {}
s1(const s1&& other) { std::cout << "moved s1\n"; }
s1(const s1& other) { std::cout << "copied s1\n"; }
};
struct s2
{
s2() {}
s2(s2&& other) { std::cout << "moved s2\n"; }
s2(const s2& other) { std::cout << "copied s2\n"; }
};
s1 f1()
{
const s1 r;
return std::move(r);
}
s2 f2()
{
const s2 r;
return std::move(r);
}
int main()
{
std::cout << "hello\n";
s1 v1= f1();
s2 v2 = f2();
}
ideone.com/JaVjwe
+4
Да, смысла от конструктора перемещения из константной ссылки нету. Я так и написал в статье. Оптимизировать что-либо такой конструктор не поможет. Чтобы получить ускорение, нужно избавиться от const. Суть статьи, как раз в том, чтобы предупредить хабрачитателей о таком неочевидном моменте.
+1
Собственно говоря, всё логично. Кто-то ожидал иного поведения?
+3
Зарегистрируйтесь на Хабре , чтобы оставить комментарий
Return by value и const variables в C++11