+3  A: 

That depends on the usage. Should GetValue("foo") = "bar" make sense? In that case, return by value does not do what you want.

FredOverflow
+2  A: 

If you can return by const reference, do. The only reason to return a memory-managing class like std::string by value is because it's a temporary string.

DeadMG
+1  A: 

This is a very "sensitive" point of C++. IMHO it's one of the weakest points of C++ design. AFAIK there's no really good choice, which will be both look and perform good.

One point that should be mentioned that RVO optimization usually does only a part of the job. Without it a typical expression like this:

std::string txt = GetValue("...");

will actually produce 2 copies! Depends on the compiler, but usually RVO optimization eliminates just one copy, however the other is still there.

valdo
Could you clarify what you mean by "... however the other [copy] is still there"? If that was the case, then the optimizer would've created buggy code! AFAIK, in such cases as you show, some compilers let the function construct the return value directly in the assigned variable (`txt` in your example) and there will never be two copies (the one in the dictionary not included in that count).
stakx
In C++0x, with rvalue references, there are explicit semantics to avoid extra temporary copies in the return value of this function. There will be only 2 copies the one that's already in settings object, and the other that will wind up in the txt variable.
Ken Bloom
+3  A: 

Actually I would probably use:

std::string GetValue(const std::string& name) const;
// or
const std::string* GetValue(const std::string& name) const;

void SetValue(std::string name, std::string value);

Setter first:

  • Passing by value in SetValue allows the compiler some optimizations that cannot be made with pass by const-reference, it's been explained in a article by Dave Abrahams, "Want Speed? Pass by Value."
  • Using a Setter is usually better, because you can check the value being set whereas with a plain reference you have no guarantee that the caller won't do anything stupid with the data.

For the getter:

  • Returning by copy seems a waste since most times you won't modify the object returned (for a settings map), however pointer or reference do mean that the object aliased will live long enough, if you can't guarantee it then the point is moot: return by value. Also copy allow to avoid exposing an internal detail, for example if you were suddenly to switch to std::wstring because you need some settings in UTF-8...
  • If you need performance, then you are ready to do some concessions in this department. However a reference does not allow you to signal the absence of the property (unless you have some magic value) while the pointer makes it easy (NULL is already cut out for you).
Matthieu M.
If I'm not mistaken, those optimizations require compiler support for rvalue references and a std lib implementation taking advantage of this. Then this should be mentioned.
sbi
He is refering to copy elision, which doesn't require move semantics.
Dennis Zickefoose
Thanks James for the link.
Matthieu M.