I've got a C++ member function of a class with a const
and non-const
overloading.
Class Example {
public:
int const & Access() const;
int & Access();
[...]
};
I wish for the const version to be preferred as the performance is way superior in my code, the non-const version causing a copy of the underlying shared object to be created to permit modification.
Right now, if my caller has a non-const Example
object, the non-const Access() method is used even if the resultant int is not modified.
Example example;
if ( modify ) {
example.Access() = 23; // Need to perform expensive copy here.
} else {
cout << example.Access(); // No need to copy, read-only access.
}
Is there a way, such as distinguishing lvalue and rvalue uses of the return value, perhaps using perfect forwarding with templates, to create a similar mechanism in C++17 that permits the caller to have one syntax which the compiler only uses the non-const version if the return value is modified?
Another example of where I need this is operator -> ()
where I have a const
and non-const
version of the operator. When calling a method that is const
I'd like the compiler to prefer the const
version of operator -> ()
.
Class Shared {
public:
int Read() const;
void Write(int value);
[...]
};
template <typename BaseClass>
class Callback {
public:
BaseClass const * operator -> () const; // No tracking needed, read-only access.
BaseClass * operator -> (); // Track possible modification.
[...]
};
typedef Callback<Shared> SharedHandle;
Shared shared;
SharedHandle sharedHandle(&shared);
if ( modify ) {
sharedHandle->write(23);
} else {
cout << sharedHandle->Read();
}
std::string
takes this route, it was originally designed to support copy-on-write semantics.operator[](n)
makes the copy whereasc_str()[n]
does not. – Accustomedoperator=
to perform the copy) – Accustomedint Access() const;
but more generally, if something complex is in play here, other than POD, then returning a reference could be better. – Conductivitystd::as_const
could be used at callside – Safeguard