Q:

C++11 const - Is my code thread-safe?

I have the following class:
class Object 
{
public:
  Object() {}

  const std::string& get_name() const
  {
    if(_name.empty()) {
      std::lock_guard<std::mutex> lock(_lock);

      // Check if its still empty. Some other thread might have gotten here first
      if(_name.empty()) {
        //Run expensive operation
        _name = get_object_name();
      }
    }

    return _name;
  }

private:
  std::string get_object_name(); // <- Expensive function

  mutable std::mutex  _lock;
  mutable std::string _name;
};

Due to the fact of get_object_name being an expensive function, I would like to do a sort of lazy initialization and only call it on the first time get_name() is called. If it is never called then I dont waste resources grabbing the name.
I am concerned about the first call to _name.empty(). Is my current code guaranteed to be thread-safe or would I need to move the lock to the top of the function?
I watched some of Herb Sutter's talks, in particular this one, where this slide comes up:
http://i.imgur.com/Jz4luYe.png
which lead me to believe that a call to empty() is thread-safe. But my variable (_name) is mutable. Does that "const == thread-safe" rule still apply here?
get_name() is the only function that can modify _name, for that matter.

A:

No, it is not thread-safe since you (read) access _name outside the mutex, which breaks synchronization.  
A possible solution is to use the std::call_once mechanism offered by the standard library.
class Object
{
public:
  Object() {}

  const std::string& get_name() const
  {
    std::call_once(flag, [&] { _name = get_object_name(); });

    return _name;
  }

private:
  std::string get_object_name() const; // <- Expensive function

  mutable std::string _name;
  mutable std::once_flag flag;
};

This guarantees that get_object_name() is not called more than once. The first call will initialize the string and concurrent calls will block until the lambda has finished.
Synchronization is fully taken care of, which means that any thread that gets the reference to the string can safely read from it.

