0

Say I have this method that creates an object of type std::vector< std::string >

const std::vector< std::string > Database::getRecordNames() {
    // Get the number of recors
    int size = this -> getRecordCount();

    // Create container
    std::vector< std::string > names;

    // Get some strings
    for ( i = 0; i < size; i++ ) {
        // Get a string
        const std::string & name = this -> getName( i );

        // Add to container
        names.push_back( name );
    }

    // Return the names
    return names;
}

And then somewhere else, I use this method

void Game::doSomething() {
    const std::vector< std::string > & names = mDatabase -> getRecordNames();

    // Do something about names
}

So, on the method Database::getRecordNames(), it returns a temporary object std::vector< std::string >. However, on the method Game::doSomething(), I placed the return value to a const std::vector< std::string > &-type object.

Is this unsafe, or is it perfectly normal to use them like this? AFAIK, temporary variables are destroyed on the end of their scope. But in our case, we reference this temporary variable, in which I believe will be destroyed after it returns the value.

Is it better to rewrite the other method so that it would use a copy of the returned value instead of a reference?

void Game::doSomething() {
    const std::vector< std::string > names = mDatabase -> getRecordNames();

    // Do something about names
}
alxcyl
  • 2,722
  • 7
  • 31
  • 47
  • Temporary values are destroyed ... *except* when they are not. What you have is the exception, and it is safe. Binding a temporary value to a const-reference extends the lifetime of the temporary value to that of the reference variable. – Kerrek SB Sep 08 '13 at 12:45
  • http://stackoverflow.com/questions/11560339/returning-temporary-object-and-binding-to-const-reference – selalerer Sep 08 '13 at 12:46
  • http://stackoverflow.com/questions/2784262/does-a-const-reference-prolong-the-life-of-a-temporary – selalerer Sep 08 '13 at 12:47
  • @KerrekSB Assuming the use of the variable stops after `Game::doSomething()`, does it get destroyed automatically? – alxcyl Sep 08 '13 at 12:48
  • @LanceGray: I meant what I said: The lifetime of the temporary value is the same lifetime as that of the reference variable to which it is bound. – Kerrek SB Sep 08 '13 at 13:11

2 Answers2

1

Returning the vector by value is perfectly safe. When you assign it to a const reference, the compiler keeps the temporary returned by Database::getRecordNames() alive until the end of the scope in which the reference lives. That is how the binding properties for a const reference are defined to work.

rohitsan
  • 1,001
  • 8
  • 31
  • 3
    Your C++11 line is dangerously confusing. Returning by value yields an rvalue, you don't have to change anything there. – juanchopanza Sep 08 '13 at 13:10
  • 1
    And how exactly would you do that? – juanchopanza Sep 08 '13 at 14:49
  • Returning an rvalue reference is almost never what you want to do: http://stackoverflow.com/questions/1116641/is-returning-by-rvalue-reference-more-efficient and http://stackoverflow.com/questions/3033689/question-about-r-value-in-c0x – Flexo Sep 08 '13 at 14:54
  • You guys are right. The compiler will automatically choose the move constuctor with the function written as is. – rohitsan Sep 08 '13 at 14:56
0

As long as your return by-value and not by-reference it is perfectly safe. The C++ compiler will keep the temporary object alive for you for as long as the reference is in scope.

selalerer
  • 3,766
  • 2
  • 23
  • 33
  • 1
    What has the compiler to do with any of this? – Kerrek SB Sep 08 '13 at 12:46
  • Well, it seems this is the component which takes C++ and translate it to machine language. Amongst other things it inserts machine code that release stack objects (adds or subtracts the stack pointer register) or allow reuse of them (in case they are in registers). It pretty much defines what the C++ language is and does. – selalerer Sep 08 '13 at 12:49
  • 1
    I would say the C++ language is what defines what the compiler should do. – juanchopanza Sep 08 '13 at 12:55
  • @juanchopanza I agree. And what is done (e.g. "keep the temporary object alive") is done by the compiler. – selalerer Sep 08 '13 at 12:58
  • 1
    Provided it is standards compliant WRT this feature :) The compiler isn't always right. – juanchopanza Sep 08 '13 at 12:58