Построение на месте для класса с удаленными конструкторами перемещения и копирования - PullRequest
0 голосов
/ 14 октября 2018

Предположим, у меня есть класс с удаленными конструкторами копирования и перемещения.Я хотел бы иметь фабричную функцию, которая создает объект на месте в зависимости от некоторого bool x, без выделения динамической памяти (без unique_ptr, new и т. Д.).

Два вопроса:

  1. Почему нижеследующее выбрасывает use of deleted function 'Foo::Foo(const Foo&&)'?Где происходит движение?

  2. Как мне достичь чего-то такого, что я пытаюсь сделать?

Спасибо.Код ниже:

EDITED :

Я пытаюсь создать одну фабричную функцию, которая может создавать родительский или дочерний элемент в зависимости от некоторой переменной X. Эта конструкция должна быть на месте с учетом удаленного копирования / перемещения.

class Foo
{
public:
    Foo(int _x) : x(_x) {}
    Foo(const Foo&) = delete;
    Foo(const Foo&&) = delete;
    int x = 10;;
};

class Bar : public Foo
{
public:
    Bar(int _y) : Foo(10), y(_y) {}
    int y;
};

Foo make_dynamic(int a, bool x) {
    if (x) {
        return Foo{a};
    } else {
        return Bar{a};
    }
}

Foo make_just_foo(int a)
{
    return Foo{a};
}

Foo make_just_bar(int a)
{
    return Bar{a};
}

int main() {
    Foo&& dynamic = make_dynamic(10, true); // works when copy/move not deleted
    Foo&& f = make_just_foo(10);
    Foo &&b2 = make_just_bar(10); // works when copy/move not deleted
}

Новая ссылка: https://coliru.stacked -crooked.com / a / a7a3eefd685f0adb

1 Ответ

0 голосов
/ 14 октября 2018

Единственный способ сделать эту работу - это использовать union (поскольку я не мог заставить его работать с использованием std::variant или std::any, поскольку оба они требуют, чтобы Foo и Bar были как минимум подвижными)

Вам нужна динамическая структура, которая будет действовать как тип возвращаемого значения:

// acts as home made std::variant
struct Dynamic {
    union {
        Foo foo;
        Bar bar;
    };

    int active;
};

и создавать ее с использованием назначенных инициализаторов C ++ 20, но уже есть и работает в текущих GCC и Clang:

Dynamic make_dynamic(int a, bool x) {
    if (x) {
        return {{.foo = Foo{2}}, 0};
    } else {
        return {{.bar = Bar{2}}, 1};
    }
}

И, наконец, мы можем получить наш динамический Foo:

Dynamic dynamic = make_dynamic(10, true);
Foo* foo = dynamic.get();

https://godbolt.org/z/7JWB6D

Вы также можете добавить методы getFoo () и getBar () для возврата ссылок наDynamic структура.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...