0

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.

kiriloff
  • 25,609
  • 37
  • 148
  • 229
  • If you're compiler allows this without so much as a warning, I'd get a new compiler. VC++ allows passing temps as non-const references, but even that is warned with appropriate (and in my opinion, mandatory) warning levels on. – WhozCraig Apr 21 '13 at 07:53
  • it does. i just want to find the work around. it is just a convenient way to ask for more clarification. – kiriloff Apr 21 '13 at 07:55

2 Answers2

3

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.

kiriloff
  • 25,609
  • 37
  • 148
  • 229
3

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.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • i am not violating const correctness in my work around, and i still make sure that `pass_by_const` is not modifying passed by const ref argment. – kiriloff Apr 21 '13 at 07:58
  • 1
    @antitrust "i am not violating const correctness" - **you do.** –  Apr 21 '13 at 08:01
  • no: everybody respects its promise, pass by const ref method will never be allowed and be able to modify argument, even if calling a pass by non const method. – kiriloff Apr 21 '13 at 08:11
  • Well if the non const version doesn't modify anything just move the code into the const version and have the non const version call the const version. Why is this so difficult? – Captain Obvlious Apr 21 '13 at 08:12
  • If a function does not modify anything it should be declared working on `const` – Basile Starynkevitch Apr 21 '13 at 08:13
  • You cannot use `reinterpret_cast` to strip away cv-qualifiers. – Luc Danton Apr 21 '13 at 08:54