As I introduced also in this question, C++11 saga of const/mutable, Provide two classes for efficiency? , in C++98, or before threads, albeit incorrect in some contexts, it was common to write class with internal hidden using mutable.
In C++11 Herb Sutter said that from now on const == thread safe
, meaning that the the mutable fields should be protected by a mutex.
so I though that some one that really know what he/she is doing can actually a more general version of the single class by doing something special in the non-const case.
struct Widget {
private:
int getValue_aux() const{
if (cacheValid) return cachedValue;
else {
cachedValue = expensiveQuery(); // write data mem
cacheValid = true; // write data mem
return cachedValue;
}
}
public:
int getValue() {
return get_value_aux(); // no lock
}
int getValue() const{
std::lock_guard<std::mutex> guard{m}; // lock mutex
get_value_aux();
} // unlock mutex
...
private:
mutable std::mutex m;
mutable int cachedValue;
mutable bool cacheValid;
...
};
So, a) a normal user can use a non-const instance of Widget
to mark that it is not intended to be used in a thread safe context, and not pay for the mutex-locking b) A user-that-really-knows-what-he-is-doing can const_cast
or wrap it as mutable
if he knows that thread safety is not going to be an issue on a particular point in the code (he/she is still storing a mutex though).
Is this a reasonable generalization of Widget at all? Or is it flawed?
Note: If you think that const
and non-const
versions should be provided for efficiency, you my find this question also interesting: C++11 saga of const/mutable, How to implement copy? and efficiently?
Aucun commentaire:
Enregistrer un commentaire