Comments 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»
Ваш пример неверен. Обратите внимание: у Саттера объекты возвращаются по значению. В этом случае можно поймать временный объект константной ссылкой, избежав лишнего копирования, и использовать его пока жива ссылка.
Ни в коем случае нельзя возвращать ссылки на локальные объекты из функций. Если Вы добавите немного вывода (output) в деструктор объекта и после получения объекта в функции main(), то убедитесь, что объект уничтожен до того, как Вы попытаетесь его использовать.
Ни в коем случае нельзя возвращать ссылки на локальные объекты из функций. Если Вы добавите немного вывода (output) в деструктор объекта и после получения объекта в функции main(), то убедитесь, что объект уничтожен до того, как Вы попытаетесь его использовать.
Вы, ребята, странные. Конечно, объект будет скопирован, потому что перемещающий конструктор не подходит по сигнатуре. Сделайте константную 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
Да, смысла от конструктора перемещения из константной ссылки нету. Я так и написал в статье. Оптимизировать что-либо такой конструктор не поможет. Чтобы получить ускорение, нужно избавиться от const. Суть статьи, как раз в том, чтобы предупредить хабрачитателей о таком неочевидном моменте.
Собственно говоря, всё логично. Кто-то ожидал иного поведения?
Sign up to leave a comment.
Return by value и const variables в C++11