简体   繁体   中英

Returning reference to temporary c++

SongPart mtm::SongStructure::getPart(int index) const {
    assert(index >= 0 && index < num_of_parts);
    return song_parts[index];
}

const SongPart& mtm::Song::operator[](int index) const {
    assert(index >= 0 && index < song_length);
    return (song_format->getPart(index));
}

I get this warning from the returning value in the second function:

returning reference to temporary [enabled by default]

How to fix this? And I can't change the returning values of each function!

You get the warning because getPart returns a copy of song_parts[index] . If it returns reference to song_parts[index] , then your code would be correct.

So you need to change the return type of getPart to SongPart const& :

SongPart const & mtm::SongStructure::getPart(int index) const {
    assert(index >= 0 && index < num_of_parts);
    return song_parts[index];
}

The const is necessary, as the function is a const member function.

Why use assert in operator[] also when you forward the call to getPart which does the assert anyway? Just write this:

const SongPart& mtm::Song::operator[](int index) const {
    //assert(index >= 0 && index < song_length); not needed!
    return (song_format->getPart(index));
}

Avoid extra bound-checks when it is not needed.

change the first function to be:

const SongPart& mtm::SongStructure::getPart(int index) const {
    assert(index >= 0 && index < num_of_parts);
    return song_parts[index];
}

the reason is the call to song_format->getPart(index) returned by value, thus create a local on the stack of the 2nd function. And if you return a reference to it, after the 2nd function returns, Boom....

If you cannot change the return type of getPart() , then you cannot usefully invoke it. Let's consider how you can access the data without invoking getPart() .

Solution 1: Call some other function:

const SongPart& mtm::SongStructure::getPartReference(int index) const {
    assert(index >= 0 && index < num_of_parts);
    return song_parts[index];
}

const SongPart& mtm::Song::operator[](int index) const {
    assert(index >= 0 && index < song_length);
    return (song_format->getPartReference(index));
}

Solution #2: return song_parts[index] directly from operator[] :

const SongPart& mtm::Song::operator[](int index) const {
    assert(index >= 0 && index < song_length);
    return (song_format->song_parts[index]);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM