如何使用户定义的类型像内置类型一样“精确地"初始化? [英] How to make a user-defined type initialize *exactly* like a built-in type?

查看:109
本文介绍了如何使用户定义的类型像内置类型一样“精确地"初始化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个包装数字类型的类型(并提供其他功能).
此外,我需要数字和包装器之间可以相互隐式转换.

I would like to make a type that wraps a numeric type (and provides additional functionality).
Furthermore, I need the number and the wrapper to be both implicitly convertible to each other.

到目前为止,我有:

template<class T>
struct Wrapper
{
    T value;
    Wrapper() { }
    Wrapper(T const &value) : value(value) { }
    // ... operators defined here ...
};

几乎是 好,但是相当的行为与内置类型相同:

It's almost good, but it doesn't quite behave the same as a built-in type:

#include <iostream>

int main()
{
    unsigned int x1, x2 = unsigned int();
    Wrapper<unsigned int> y1, y2 = Wrapper<unsigned int>();

    std::cerr << x1       << std::endl;  // uninitialized, as expected
    std::cerr << y1.value << std::endl;  // uninitialized, as expected

    std::cerr << x2       << std::endl;  // zero-initialized, as expected
    std::cerr << y2.value << std::endl;  // uninitialized!?!
}

我有什么办法可以设计Wrapper这样的语句

Is there any way for me to design the Wrapper such that statements like

Wrapper<unsigned int> y2 = Wrapper<unsigned int>();

初始化内部的value,但 强制使用类似

initialize the value inside, but without forcing statements like

Wrapper<unsigned int> y1;

也要这样做吗?

换句话说,是否有可能使类型在初始化方面与内置类型完全相同的类型?

In other words, is it possible to make a type that behaves exactly the same as a built-in type in terms of initialization?

推荐答案

更新后的答案

好吧,就像dyp指出的那样,我和其他所有人都错了.您可以使用默认构造函数通过= default实现您想做的事情:

Okay, so as dyp points out, I and everyone else was wrong. You can achieve what you want to do by = default with the default constructor:

 Wrapper() = default ;
           ^^^^^^^^^

之所以起作用,是因为没有初始化程序,您将获得我之前概述的相同行为,但是当您使用值初始化时,行为将按照第 8 段中所述进行更改:

This works because without an initializer you obtain the same behavior I outline before but when you use value initialization the behavior changes as outlined in paragraph 8:

-如果T是(可能具有cv资格的)非工会类类型,而没有用户提供或删除的默认构造函数,则该对象将被初始化为零. -普通的默认构造函数,默认初始化;

— if T is a (possibly cv-qualified) non-union class type without a user-provided or deleted default constructor, then the object is zero-initialized and, if T has a non-trivial default constructor, default-initialized;

原始答案

我认为没有一种方法可以使您的工作如愿以偿.类类型的行为与内置类型不同,我们可以从标准条款草案8.5 Initializers 段落 12 中看到这一点,(强调我的前进 ):

I don't think there is a way to make this work the way you would like. Class types act differently that builtin types we can see this from the draft standard section 8.5 Initializers paragraph 12 which says (emphasis mine going forward):

如果未为对象指定初始化程序,则该对象将被默认初始化;如果不执行初始化,则具有自动或动态存储持续时间的对象的值不确定. [注意:具有静态或线程存储持续时间的对象将初始化为零,请参见3.6.2. —尾注]

If no initializer is specified for an object, the object is default-initialized; if no initialization is performed, an object with automatic or dynamic storage duration has indeterminate value. [ Note: Objects with static or thread storage duration are zero-initialized, see 3.6.2. —end note ]

我们可以看到,对于类来说,结果与 7 段落中的内置类型不同:

and we can see this has different results for classes than built-in types from paragraph 7 which says:

默认初始化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);

-如果T是数组类型,则每个元素都将默认初始化;

— if T is an array type, each element is default-initialized;

否则,不执行初始化.

,如果我们在第二个案例Wrapper<unsigned int>()的段落 11 中看到:

and if we look at paragraph 11 for the second case Wrapper<unsigned int>() it says:

一个对象的初始化程序是一组空括号,即(),应进行值初始化.

,然后回到第 8 段:

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

To value-initialize an object of type T means:

-如果T是(可能具有cv限定的)类类型(第9条),没有默认构造函数(12.1)或用户提供或删除的默认构造函数,则该对象已默认初始化; [...]

— if T is a (possibly cv-qualified) class type (Clause 9) with either no default constructor (12.1) or a default constructor that is user-provided or deleted, then the object is default-initialized; [...]

所以我们最终会得到相同的行为.

So we end up with the same behavior.

Praetorian aschepler 都为您提供了一些选项,它们的工作方式略有不同,但似乎使用不同的语法实现了您想要的行为.

Both Praetorian and aschepler gave you options that work slightly differently but appear to achieve the behavior you would like just not with the same syntax.

这篇关于如何使用户定义的类型像内置类型一样“精确地"初始化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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