使用已删除的默认构造函数的C

使用已删除的默认构造函数的C

本文介绍了使用已删除的默认构造函数的C ++直接列表初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下类定义.我提供了一个私有的 x 来确保它不是聚合的.

I have the following class definition. I included a private x to make sure it is not an aggregate.

class A {
 private:
  int x;

 public:
  A() = delete;
  A(std::initializer_list<int>) { printf("init\n"); }
};

现在,如果我使用 A a = A {} 初始化此对象,它将说 A :: A()被删除.我猜它正在尝试调用 A :: A(),但是它已被删除.如果我注释掉该行,则会自动生成 A :: A().然后,如果我运行此代码,我可以看到它正在调用 A :: A(std :: initializer_list< int>)

Now if I initialize this object with A a = A{}, it will say A::A() is deleted. I guess it is trying to call A::A() but it is deleted. If I comment out that line, so A::A() is automatically generated. Then if I run this code, I could see that it is calling A::A(std::initializer_list<int>)!

更令人困惑的是,如果我定义 A()= default ,则初始化会再次调用 A :: A().

And more confusing, if I define A() = default, the initialization calls A::A() again.

有人能指出我正确理解这种行为的正确方向吗?谢谢!

Can anyone point me to the right direction of understading this behavior? Thanks!

我正在使用带有标志 -std = c ++ 17 的G ++ 6.3.0.

I'm using G++ 6.3.0 with flag -std=c++17.

推荐答案

行为正确.

首先:

// Calling
A a = A{}; // equals A a = A();,

是列表初始化习惯用法的方便统一.请参阅: https://stackoverflow.com/a/9020606/3754223

which was a convenience uniformization of the list-initialization idiom.Refer to: https://stackoverflow.com/a/9020606/3754223

class A {
     private:
         int x;

     public:
         **A() = delete;**
         A(std::initializer_list<int>) { printf("init\n"); }
};

如上所述,A a = A {}将是... = A(),将其删除.

As said above, A a = A{} will be ... = A(), which is deleted.

class A {
     private:
         int x;

     public:
         A(std::initializer_list<int>) { printf("init\n"); }
};

在这种情况下,没有提供默认的构造函数,因为您已定义了initializer-list构造函数.因此{}被隐式转换为空的初始值设定项列表!

In this case, there's no default constructor provided, since you have your initializer-list constructor be defined. Consequently {} is converted to an empty initializer list implicitely!

class A {
     private:
         int x;

     public:
         **A() = default;**
         A(std::initializer_list<int>) { printf("init\n"); }
};

在这种情况下,可以使用空的默认构造函数,并将A {}转换回A(),使其被调用.

In this case the empty default constructor is available and A{} is converted back to A(), causing it to be called.

请参阅以下页面并对其进行详尽的阅读. http://en.cppreference.com/w/cpp/utility/initializer_list http://en.cppreference.com/w/cpp/language/value_initialization

Please refer to the below pages and get a thorough read into it.http://en.cppreference.com/w/cpp/utility/initializer_listhttp://en.cppreference.com/w/cpp/language/value_initialization

使用:

A a = {{}};

将导致总是初始化构造器列表构造函数被调用,因为外面的花括号表示初始化列表,而内部的括号表示零构造元素.->非空的初始值设定项列表...(请再次参见上方的stackoverflow链接!)

Would cause that ALWAYS the initializer-list constructor is called, as the outer-curly-brackets denoted the init-list, and the inner a zero-constructed element. -> Non-empty initializer-list... (See stackoverflow link above again!)

顺便说一句,考虑到这是一个非常棘手的部分,我不明白为什么这个问题被否决了...

And btw, I cannot understand why the question is downvoted, considering that this is a really tricky part...

这篇关于使用已删除的默认构造函数的C ++直接列表初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 12:22