4

Possible Duplicate:
Is there some ninja trick to make a variable constant after its declaration?

Consider the following minimal example:

void MutateData(std::string&);

int main()
{
  std::string data = "something that makes sense to humans.";

  ::MutateData(data); // Mutates 'data' -- e.g., only changes the order of the characters.

  // At this point, 'data' should never be changed.
  // Mixing the above with const-correct code seems ugly.
}

Currently, I'm doing:

namespace
{
  std::string PrepareData(std::string data)
  {
    ::MutateData(data);

    return data;
  }
}

int main()
{
  const std::string data = ::PrepareData("something that makes sense to humans.");
}

What are some elegant solutions to simulating const beyond the point of declaration?


EDIT: I forgot to clarify that I can't easily (not my code) change MutateData.

Community
  • 1
  • 1
  • This looks like a duplicate of http://stackoverflow.com/questions/3669315/is-there-some-ninja-trick-to-make-a-variable-constant-after-its-declaration/3669477#3669477 – Mark B Sep 15 '10 at 17:01
  • Thanks for that. I knew there should have been a question on this already. Too bad I didn't find it before posting. – melmitchell Sep 15 '10 at 17:10
  • Some topics are hard to search for, and there is no shame it not finding them. In some ways your title is superior to the earlier one, making this a prime candidate for being left closed but un-deleted as a sign post for future visitors struggling with the same searching problem. – dmckee --- ex-moderator kitten Sep 15 '10 at 17:18

2 Answers2

2

You can use a const reference.
Take a look at http://herbsutter.com/2008 for an explanation about why it works.

log0
  • 10,489
  • 4
  • 28
  • 62
1

What about:

string MakeData(string const&)
{
    ...
    return string(...);  // for return value optimization
}

followed by

int main()
{
    string const& str = MakeData("Something that makes sense to humans");
}

The difference with what you do is using a const reference, and only one function. If you cannot change MutateData, do what you suggested (with the const reference though)

Alexandre C.
  • 55,948
  • 11
  • 128
  • 197
  • There is no clear advantage I can think of in using a constant reference compared to a real variable. In the case of a variable, most compilers will elide the extra copy and build the return object in place. In the reference version, the compiler still needs to keep the temporary (reserve the space in the stack where the return value was created) and possibly create a reference (or avoid creating it, since a reference is an alias it need not create one but just use the identifier to refer to the temporary, which is exactly what the return value optimization would do). – David Rodríguez - dribeas Sep 15 '10 at 18:01
  • @David: You're of course right, both are exactly equivalent. But the const reference trick is quite idiomatic... – Alexandre C. Sep 15 '10 at 21:01