Как стать автором
Обновить

Комментарии 8

Возможно не совсем в тему статьи (хотя и близко), но хочется вспомнить о возврате локальных (временных) объектов по константной ссылке:

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(), то убедитесь, что объект уничтожен до того, как Вы попытаетесь его использовать.
Спасибо за пояснение, я пропустил важный момент, что объект возвращается не по ссылке.
Вы, ребята, странные. Конечно, объект будет скопирован, потому что перемещающий конструктор не подходит по сигнатуре. Сделайте константную r-value ссылку и будет вам перемещение константных объектов. Другой вопрос — зачем

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. Суть статьи, как раз в том, чтобы предупредить хабрачитателей о таком неочевидном моменте.
Ну, что он сможет соптимизировать, зависит только от вас (и от количества членов с атрибутом mutable в s :) Просто момент довольно очевиден, по-моему.
Собственно говоря, всё логично. Кто-то ожидал иного поведения?
Если задуматься, то да — все логично и об этом нужно постоянно помнить. А если просто писать по привычке, то можно упустить.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории