显式默认构造函数的目的 [英] Purpose of Explicit Default Constructors

查看:159
本文介绍了显式默认构造函数的目的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近注意到C ++ 0x中的一个类需要一个显式的默认构造函数.但是,我无法提出一种方案,在该方案中可以隐式调用默认构造函数.这似乎是一个毫无意义的说明符.我认为也许不允许Class c;赞成Class c = Class();,但是事实并非如此.

I recently noticed a class in C++0x that calls for an explicit default constructor. However, I'm failing to come up with a scenario in which a default constructor can be called implicitly. It seems like a rather pointless specifier. I thought maybe it would disallow Class c; in favor of Class c = Class(); but that does not appear to be the case.

C ++ 0x FCD中的一些相关引号,因为它使我更容易浏览[如果不在同一位置,C ++ 03中也存在相似的文本]

Some relevant quotes from the C++0x FCD, since it is easier for me to navigate [similar text exists in C++03, if not in the same places]

12.3.1.3 [class.conv.ctor]

12.3.1.3 [class.conv.ctor]

默认构造函数可以是显式构造函数;这样的构造函数将用于执行默认初始化或值初始化(8.5).

A default constructor may be an explicit constructor; such a constructor will be used to perform default-initialization or value initialization (8.5).

接着提供了一个显式默认构造函数的示例,但它只是模仿了我上面提供的示例.

It goes on to provide an example of an explicit default constructor, but it simply mimics the example I provided above.

8.5.6 [decl.init]

8.5.6 [decl.init]

默认初始化T类型的对象的意思是:

To default-initialize an object of type T means:

-如果T是(可能是cv限定的)类类型(第9条),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化格式不正确);

— if T is a (possibly cv-qualified) class type (Clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

8.5.7 [decl.init]

8.5.7 [decl.init]

要对T类型的对象进行值初始化,则意味着:

To value-initialize an object of type T means:

-如果T是具有用户提供的构造函数(12.1)的(可能是cv限定的)类类型(第9条),则调用T的默认构造函数(如果T没有可访问的默认构造函数);

— if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

在两种情况下,标准调用都会调用默认构造函数.但是,如果默认构造函数不明确,将会发生这种情况.为了完整起见:

In both cases, the standard calls for the default constructor to be called. But that is what would happen if the default constructor were non-explicit. For completeness sake:

8.5.11 [decl.init]

8.5.11 [decl.init]

如果未为对象指定初始化程序,则该对象将被默认初始化;

If no initializer is specified for an object, the object is default-initialized;

据我所知,这只是没有数据的转换.这没有道理.我能想到的最好的方法是:

From what I can tell, this just leaves conversion from no data. Which doesn't make sense. The best I can come up with would be the following:

void function(Class c);
int main() {
  function(); //implicitly convert from no parameter to a single parameter
}

但是显然,这不是C ++处理默认参数的方式.还有什么会使explicit Class();的行为不同于Class();?

But obviously that isn't the way C++ handles default arguments. What else is there that would make explicit Class(); behave differently from Class();?

产生此问题的具体示例是std::function [20.8.14.2 func.wrap.func].它需要几个转换构造函数,没有一个被标记为显式,但是默认构造函数是.

The specific example that generated this question was std::function [20.8.14.2 func.wrap.func]. It requires several converting constructors, none of which are marked explicit, but the default constructor is.

推荐答案

这将声明一个显式的默认构造函数:

This declares an explicit default constructor:

struct A {
  explicit A(int a1 = 0);
};

A a = 0; /* not allowed */
A b; /* allowed */
A c(0); /* allowed */

在没有参数的情况下(如以下示例所示),explicit是多余的.

In case there is no parameter, like in the following example, the explicit is redundant.

struct A {
  /* explicit is redundant. */
  explicit A();
};

在某些C ++ 0x草案(我相信它是n3035)中,它通过以下方式产生了不同:

In some C++0x draft (I believe it was n3035), it made a difference in the following way:

A a = {}; /* error! */
A b{}; /* alright */

void function(A a);
void f() { function({}); /* error! */ }

但是在FCD中,他们对此进行了更改(尽管,我怀疑他们没有考虑到这个特殊原因),因为这三种情况均 value-initialize 各自的对象.值初始化不会进行重载解析,因此不会在显式构造函数上失败.

But in the FCD, they changed this (though, I suspect that they didn't have this particular reason in mind) in that all three cases value-initialize the respective object. Value-initialization doesn't do the overload-resolution dance and thus won't fail on explicit constructors.

这篇关于显式默认构造函数的目的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆