【问题标题】:In place construction for class with deleted move and copy constructors删除移动和复制构造函数的类的就地构造
【发布时间】:2018-10-14 15:11:26
【问题描述】:

假设我有一个删除了复制和移动构造函数的类。我想要一个工厂函数,它根据一些 bool x 构造对象,而不分配动态内存(没有 unique_ptr、new 等)。

两个问题:

  1. 为什么下面会抛出use of deleted function 'Foo::Foo(const Foo&&)'?移动发生在哪里?

  2. 我怎样才能达到我想要做的效果?

谢谢。代码如下:

已编辑

我要做的是创建一个单一的工厂函数,该函数可以根据某个变量 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

【问题讨论】:

  • 但你到底想做什么?
  • 看起来你想要Foo x{10};
  • @juanchopanza 更新了我真正想要的内容。我想要一个可以创建 Foo 或 Bar 的工厂函数。问题是由于已删除的复制/移动,它需要就位。 Bar 继承自 Foo
  • 如果您按值返回(对象切片),那将不起作用。如果您有一组无限类型的要支持,我建议您查看 type erasure , 或 std::variant 如果有界。
  • 您说您希望“就地”创建一个对象。你是什​​么意思?在什么地方,或者在什么地方?工厂函数如何知道对象需要创建在什么地方?

标签: c++ c++11 inheritance move


【解决方案1】:

我可以完成这项工作的唯一方法是使用union,(因为我无法使用std::variantstd::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 结构的引用。

【讨论】:

    猜你喜欢
    • 2016-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 2013-08-19
    • 2018-09-23
    • 1970-01-01
    相关资源
    最近更新 更多