For the sake of avoiding code duplication when dealing with const-overload I wrote something like this:
#include <memory>
class A
{
std::shared_ptr<int> _data;
public:
const A lightCopy() const
{
A a;
a._data = _data;
return a;
}
A lightCopy()
{
using const_a_t = const A;
const_a_t &const_me = *this;
return const_me.lightCopy(); // const object here
}
};
int main()
{
A a;
auto b = a.lightCopy();
}
const_cast
is used in non-const version because otherwise it would be a non-const function call in const-method that will probably modify the object and will get away with it unnoticed (because of const_cast
). And const-casting from non-const to const shouldn't cause any problems.
And question here is: since I can't const_cast an object — is it possible that because invoked lightCopy()
returns const object and actual return type is not const — RVO won't be possible and an additional copy will be made?
Copy elision of temporary objects is permitted if the source and the destination have the same "cv-unqualified type" according to 12.8 [class.copy] paragraph 31 third item in the list:
when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type, the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move
That is, the quoted code copy elision is allowed.
Instrumenting the destructor in the original example shows that clang, Intel's compiler, and EDG's frontend elide the copies while gcc does not. That is, there are only two destructor calls implying that all possibly elidable copies are elided. The copies are elided independent of how b
is declared. I have declared b
using auto
, A
, and A const
.