找不到使保证的返回值优化有效的方法

时间:2019-10-20 21:00:16

标签: c++ c++17 rvo nrvo

当删除move构造函数时,为什么clang在call to deleted constructor of 'Block<Tuple>::Self' (aka 'Block<Tuple>')的调用中说Block<Tuple>::a1()

c ++ 17 clang版本9.0.0(标签/ RELEASE_900 / final) 目标:x86_64-pc-linux-gnu 螺纹型号: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();
    }
};

根据我的阅读,如果删除副本并移动构造函数,我本可以保证rvo。编译器会在无法执行rvo并且代码无法编译的情况下抱怨。例如,当我删除复制构造函数并仅通过抛出错误定义移动对象时,由于我没有错误,他实际上优化了a1的调用。但是当我删除move构造函数时,代码甚至无法编译。

1 个答案:

答案 0 :(得分:0)

此代码:

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

不属于所谓的“保证复制删除”。它仍然具有与较早版本的C ++相同的行为,即,它是一个复制省略上下文,但是复制/移动构造必须有效,并且编译器不必执行省略。

a2代码已得到“保证”,因此您不应从中得到错误。