[Filesystem] V3 interface inconsistency

Hello I came across the following interface inconsistency in Boost.Filesystem V3 (Boost 1.46.0) in boost::filesystem::path Windows: const std::string string() const std::wstring& wstring() Linux: const std::string& string() const std::wstring wstring() We converted V2 code looking like this (necessary since filename() in V3 returns a path instead of a string): const std::string& filename=path.filename(); The converted V3 code: const std::string& filename=path.filename().string(); Obviously this code crashes in Linux since filename() returns a temporary object and string() returns a reference to one of its members. However this code works in Windows due to the different return types. My question: Wouldn't it make sense for all methods to return a value instead of a reference? It would ease the transition from V2 to V3 and avoid subtle programming errors. Regards, Peter.

On Thu, Feb 24, 2011 at 3:13 AM, Peter Klotz
reference?
It would ease the transition from V2 to V3 and avoid subtle programming errors.
This is a more general comment than just about Boost.Filesystem. I've pretty much concluded that string methods, at least virtual methods, should always return std::string rather than const std::string&. An accessor that returns a const reference to a data member is little better than direct read access to the data member. The reason we use accessors in the first place is to permit us to later introduce additional logic if need be: to return a computed value. But returning a reference forbids that. I've been burned a few times by a base class with a virtual method returning const std::string&. Of course the base-class implementation simply returns a data member, and it remains fine as long as no subclass needs to override it with real logic. But the first time you have to compute a return value in some override method -- you have to change ALL the return types for that method in the whole class hierarchy. Gack! Pass by const reference, but return by value.

On Sat, Feb 26, 2011 at 3:27 AM, Nat Linden
An accessor that returns a const reference to a data member is little better than direct read access to the data member. The reason we use accessors in the first place is to permit us to later introduce additional logic if need be: to return a computed value. But returning a reference forbids that.
Stepping back a little further I'd be inclined to ask why the accessor
exists at all. The great get/set debate!
I've been burned a few times by a base class with a virtual method returning const std::string&. Of course the base-class implementation simply returns a data member, and it remains fine as long as no subclass needs to override it with real logic. But the first time you have to compute a return value in some override method -- you have to change ALL the return types for that method in the whole class hierarchy. Gack!
Pass by const reference, but return by value.
That would seem to fly in the face of copy elision - see http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/ - Rob.

On Sat, Feb 26, 2011 at 3:50 PM, Robert Jones
An accessor that returns a const reference to a data member is little better than direct read access to the data member. The reason we use accessors in the first place is to permit us to later introduce additional logic if need be: to return a computed value. But returning a reference forbids that.
Stepping back a little further I'd be inclined to ask why the accessor
exists at all. The great get/set debate!
/me backs slowly away from potential rwar
Pass by const reference, but return by value.
That would seem to fly in the face of copy elision - see http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/
Hmm! Thanks for passing me the reference (as it were). So let's say my real point is: return by value. I may have to rethink my policy on accepting parameters. <veering dangerously off topic>For an rvalue actual argument, I think I see that a modern compiler can treat a value parameter as efficiently as a const reference parameter. But across translation units, wouldn't an lvalue actual argument necessarily be more efficient when received by a const reference than by a value parameter? Especially if the function body only examines the parameter without needing to copy it?</veering>
participants (3)
-
Nat Linden
-
Peter Klotz
-
Robert Jones