Re: What is the idiom for cached calculations preserving const-ness?
On 16 Apr., 06:33, t...@42.sci.utah.edu wrote:
Jesse Perla <jessepe...@gmail.com> wrote:
[snip]
Two solutions I can think of:
1. Make p_m_inverse_ mutable. Mutable is generally evil in
multithreaded code, though (at least IMHO).
2. create a non-const `compute_inverse()' method:
struct my_class {
...
void compute_inverse() {
p_m_inverse_ = shared_ptr<matrix>(new ...);
}
class InverseNotComputed;
const matrix& matrix_inverse() const {
if(p_m_inverse_) {
throw InverseNotComputed();
}
return p_m_inverse_;
}
etc.
Your concern about multithreading and mutable is not unfounded, but
your suggestion with the non-const public compute function makes
matters actually worse.
* First of:
how should the client of matrix_inverese() const fulfill the
precondition of calling compute_inverse() when all he got is a const
reference? (Solution: It's the responsibility of the changing clients
to do it. -> But what happens if they don't and you cannot change
them?)
* Second:
Your solution is subject to race conditions consider:
my_class c;
c.do_some_changes();
....
c.compute_inverse();
// Checkpoint!
try {
matrix i = c.matrix_inverse();
} catch (...) {
// BADABOOM!!!
}
If another thread changes your c instance somewhere around
"checkpoint", matrix_inverse() fails.
So all that considered, I think the solution with using mutable is
much better. You simply (well as far as there is a "simply" in
threaded code) add proper locking inside of my_class and your done.
HTH
Fabio
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]