有没有办法在 C++20 中创建不可复制的聚合结构?

问题描述 投票:0回答:2

在 C++20 中,聚合不能有用户声明或继承的构造函数(因此您不能将它们声明为删除)。 那么有没有办法让结构仍然是一个聚合,但不可复制?

c++ aggregate c++20
2个回答
1
投票

根据 aggregates 上的规则,您不能在聚合本身上删除构造函数,而是在基类上,例如:

struct bar{
    // having the defaulted constructor is required for C++20 aggregate initialization to work
    bar() = default;
    // prevents copy and deletes other constructors
    bar(const bar&) = delete;
};

struct foo : bar{
    int a;
};

然后您可以使用聚合语法对其进行初始化:

foo b {{}, 1};

// or

foo c { .a = 1};

这将(大部分)正常工作:工作示例

然而,存在明显的权衡,因为添加继承会破坏某些功能。例如:https://godbolt.org/z/P8Ea61oh3

std::optional<foo> e(std::in_place, {}, 1);

会坏的。


1
投票

添加一个不可复制的基数是可行的,但它的缺点是基数是first,所以它会扰乱paren初始化。做完全相同的想法,但把它放在last更好:

struct noncopyable {
    noncopyable() = default;
    noncopyable(noncopyable&&) = default;
    noncopyable& operator=(noncopyable&&) = default;
};

struct foo {
    int i;
    // ... more members here ...
    [[no_unique_address]] noncopyable _ = {};
};

从聚合中删除 any 用户声明的构造函数的论文是 P1008。非常不幸的是,我们基本上绕了一个圈——在 C++03 中,为了使类不可复制,您将复制构造函数声明为私有的。在 C++11 中,我们可以明确地删除它,这使得代码中发生的事情更加清晰。在 C++20 中,我们取消了聚合的能力,所以现在我们又回到了奇怪的恶作剧。

© www.soinside.com 2019 - 2024. All rights reserved.