A return type changed from const Bar& getBar() to const Bar getBar().
If i use:
const auto& bar = getBar();
and the return type changes. I have a reference on a temporary object.
If i use:
const auto bar = getBar();
i always make a copy of Bar.
What is The best practice for this problem?
class Bar {
public:
Bar() = default;
Bar(const Bar&) = default;
Bar(Bar&&) = delete;
Bar& operator=(const Bar&) = delete;
Bar& operator=(const Bar&&) = delete;
void setValue(int i);
int value() const;
private:
int m_i = 0;
};
class Foo {
public:
Foo(Bar& bar) : m_bar(bar) {}
Foo(const Foo&) = delete;
Foo(Foo&&) = delete;
Foo& operator=(const Foo&) = delete;
Foo& operator=(const Foo&&) = delete;
const Bar& giveMeBar();
private:
Bar& m_bar;
};
int main() {
auto bar = std::make_unique<Bar>();
auto foo = std::make_unique<Foo>(*bar.get());
const auto& barFromFoo = foo->giveMeBar();
bar->setValue(2);
std::cout << "original bar: " << bar->value() << std::endl;
std::cout << "bar from foo: " << barFromFoo.value() << std::endl;
}
What is actually "best practice" is opinion based. I will only try to explain why your premise isn't sound so you can make up your opinion on what is a good practice yourself and/or can judge some guideline on the matter.
The lifetime of the temporary is extended and bound to the constant reference. There is no problem. If you want to avoid an unnecessary copy then don't make a copy. In the shown code you can replace
const Bar& giveMeBar();withconst Bar giveMeBar();without any issues.For illustration consider this example:
Output:
PS:
autodoes not change anything about that. The following are pairwise equivalent: