gpt4 book ai didi

c++ - 为什么这段代码在 C++17 中编译没有错误?

转载 作者:行者123 更新时间:2023-12-02 09:38:54 25 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





When is a private constructor not a private constructor?

(3 个回答)


11 个月前关闭。




我已经删除了所有的构造函数,即使下面的代码运行良好。如何以及为什么?

class Ax
{
public:

Ax() = delete;
Ax(Ax const&)=delete;
Ax(Ax&&)=delete;
void operator=(Ax const&)=delete;
void operator=(Ax&&)=delete;

void print()
{
cout << "Hello \n";
}
};

int main(int argc, char** argv)
{
Ax{}.print();
return 0;
}

最佳答案

(有关此主题的完整演练,请参阅博客文章 The fickle aggregate)

聚合初始化
类(class)Ax是 C++11、C++14 和 C++17 中的聚合,因为它没有用户提供的构造函数,这意味着 Ax{}是聚合初始化,绕过任何用户声明的构造函数,甚至是删除的构造函数。

struct NonConstructible {
NonConstructible() = delete;
NonConstructible(const NonConstructible&) = delete;
NonConstructible(NonConstructible&&) = delete;
};

int main() {
//NonConstructible nc; // error: call to deleted constructor

// Aggregate initialization (and thus accepted) in
// C++11, C++14 and C++17.
// Rejected in C++20 (error: call to deleted constructor).
NonConstructible nc{};
}
什么是聚合类的定义在各种标准版本(C++11 到 C++20)中发生了变化,这些规则可能会产生一些令人惊讶的结果。从 C++20 开始,特别是由于
  • P1008R1: Prohibit aggregates with user-declared constructors

  • 大多数经常令人惊讶的聚合行为已得到解决,特别是不再允许聚合具有用户声明的构造函数,这是对类作为聚合的更严格要求,而不仅仅是禁止用户提供的构造函数。

    用户提供的或仅用户声明的显式默认构造函数
    请注意,提供一个显式默认(或删除)的外部定义算作用户提供的构造函数,这意味着在以下示例中, B有一个用户提供的默认构造函数,而 A才不是:
    struct A {
    A() = default; // not user-provided.
    int a;
    };

    struct B {
    B(); // user-provided.
    int b;
    };

    // Out of line definition: a user-provided
    // explicitly-defaulted constructor.
    B::B() = default;
    结果是 A是一个聚合,而 B不是。这反过来意味着 B 的初始化通过空的 direct-list-init 将导致其数据成员 b处于未初始化状态。对于 A ,但是,相同的初始化语法将导致(通过 A 对象的聚合初始化和其数据成员 a 的后续值初始化)其数据成员 a 的零初始化:
    A a{};
    // Empty brace direct-list-init:
    // -> A has no user-provided constructor
    // -> aggregate initialization
    // -> data member 'a' is value-initialized
    // -> data member 'a' is zero-initialized

    B b{};
    // Empty brace direct-list-init:
    // -> B has a user-provided constructor
    // -> value-initialization
    // -> default-initialization
    // -> the explicitly-defaulted constructor will
    // not initialize the data member 'b'
    // -> data member 'b' is left in an unititialized state
    这可能会让人感到意外,并且存在读取未初始化数据成员 b 的明显风险。未定义行为的结果:
    A a{};
    B b{}; // may appear as a sound and complete initialization of 'b'.
    a.a = b.b; // reading uninitialized 'b.b': undefined behaviour.

    关于c++ - 为什么这段代码在 C++17 中编译没有错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64114701/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com