Question

I have this function pass_by_const(const std::string& s) which wants to call pass_by_non_const(std::string& s).

If I have this method's definition

pass_by_const(const std::string& s)
{
    pass_by_non_const(s);
}

would compiler yield at me, and are there work arounds ? I fear that pass_by_non_const modifies s behind my back.

Was it helpful?

Solution

What happens with

pass_by_const(const std::string& s)
{
    pass_by_non_const(s);
}

is: pass_by_const has const argument std::string s, so it is not allowed to modify the string s defined in enclosing scope and passed to him as an argument. However, pass_by_non_const is allowed to modify s. This raises compiler error at compile time.

A local non-const copy of s can be passed to pass_by_non_const however. Then, the local copy may be modified in the scope of pass_by_non_const, whereas the enclosing scope's s passed as an argument to pass_by_const is not altered.

Right way to write the method is then

pass_by_const(const std::string& s)
{
    std::string local_copy = s;
    pass_by_non_const(local_copy );
}

No more compile time error, local_copy may be modified in most inner scope, whereas s from enclosing scope won't be, which abide by the pass-by-const-ref-ness of the pass_by_const method.

OTHER TIPS

You should not even want to call pass_by_non_const from pass_by_const because if an argument is a const reference you are "promising" to not modify it.

If you want to violate the type system (which is a bad thing), you could do ugly things like

 pass_by_const(const std::string& s)
 {
    pass_by_non_const(const_cast<std::string&>(s));
 }

But the point is that doing so is wrong, and could be undefined behavior. So anything bad could happen (a crash, or even the program accidentally doing what you want).

If you want to obey the type system and avoid violating invariants, make a local copy like suggested in antitrust's answer. Of course making a local copy might be costly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top