не могу найти способ обеспечить гарантированную оптимизацию возвращаемого значения - PullRequest
0 голосов
/ 21 октября 2019

Почему Clang говорит call to deleted constructor of 'Block<Tuple>::Self' (aka 'Block<Tuple>') в вызове Block<Tuple>::a1(), когда я удаляю конструктор перемещения?

c ++ 17 clang версия 9.0.0 (tags / 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, поскольку я не получил ошибок. Но когда я удаляю конструктор перемещения, код даже не компилируется.

1 Ответ

0 голосов
/ 21 октября 2019

Этот код:

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

не является частью так называемого "гарантированного разрешения на копирование". Он по-прежнему имеет то же поведение, что и в более старых версиях C ++, то есть это контекст разрешения копирования, но конструкция копирования / перемещения должна быть действительной, и компилятор не должен выполнять удаление.

a2 код "гарантирован" как таковой, и вы не должны получать ошибки от этого.

...