简体   繁体   中英

can't find a way to make garanteed return value optimization work

Why the clang says call to deleted constructor of 'Block<Tuple>::Self' (aka 'Block<Tuple>') in the call of Block<Tuple>::a1() when I delete the move constructor?

c++17 clang version 9.0.0 (tags/RELEASE_900/final) Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin

template<typename tRecord>
struct Block {

    using Self = Block<tRecord>;

    Size mUsedBytes;
    bool mModified;

    union Data {
        char mBytes[4_KB];
        tRecord mRecord;
    };
    Data mData;

    Block() {
        mardCpp::Log::info("constructing");
    };

    Block(const Block &block) = delete;
    Block(Block &&block) = delete;

    static Self a1() {
        Self block;
        return block;
    }

    static Self a2() {
        return Self();
    }
};

From what I've readed, I could have garanteed rvo if I deleted the copy and move constructors. The compiler would complain in situations where he could not do rvo and the code would not compile. For instance, when I delete the copy constructor and define the move one with just throwing an error, he actually optimizes the calling of a1, since I got no errors. But when I delete the move constructor, the code does not even compile.

This code:

static Self a1() {
    Self block;
    return block;
}

is not part of the so-called "guaranteed copy elision". It still has the same behaviour as in older versions of C++, ie it is a copy elision context but the copy/move construction must be valid and the compiler doesn't have to perform the elision.

The a2 code is "guaranteed" as such and you should not get errors from that.

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