直接初始化和复制初始化引用

时间:2021-12-06 19:57:29

I have been reading "C++ primer". For the initialization of object, C++ supports 2 forms of initialization: direct and copy. but the book does not refer the initialization of reference. And in the book I have never seen the direct initialize(if exists) of a reference. All is the copy one like:

我一直在读《c++入门》。对于对象的初始化,c++支持两种初始化形式:直接初始化和复制初始化。但书中并未提及参考的初始化。在书中,我从未见过直接初始化(如果存在)的引用。所有的都是副本,比如:

int i;
int &j = i;//but not int &j(i);which also works in my experiment

I want to know that is it the same that are going on underneath for the initialization of a reference. for the following codes:

我想知道在初始化引用时,它是否和下面发生的一样。下列代码:

string null_book = "9-999-99999-9";

the initialization progress is first create a temporary string object tmp(for instance) that will direct initialized with a c style string parameter, and then initialize the variable null_book with the copy Constructor. That make sense to me. for this one:

初始化过程首先创建一个临时字符串对象tmp(例如),该对象将使用c样式的字符串参数直接初始化,然后使用复制构造函数初始化变量null_book。这对我来说很有意义。这一个:

int &j = i;

will ref j be initialized the same way? That will be a temp reference it &t(for example) initialized by i and then initialize j with t? that doesnt make sense??? Why the book never use the direct initialization for reference? Thanks for your attention!

ref j会以同样的方式初始化吗?那将是一个temp引用它与(例如)被i初始化然后用t初始化j ?不合理? ? ?为什么这本书从不使用直接初始化作为参考?谢谢你的关注!

3 个解决方案

#1


6  

The main differences between direct-initialization and copy-initialization are covered in section 8.5, paragraph 17 of the standard. In general, the difference is that for class types in copy-initialization, explicit constructors are not considered (only converting constructors are considered) and a possibly elided copy is made; in direct-initialization explicit constructors are considered and the target is constructed directly. From section 8.5 of the standard:

直接初始化和复制初始化之间的主要区别载于标准第8.5节第17段。一般而言,不同之处在于,对于复制初始化中的类类型,不考虑显式构造函数(只考虑转换构造函数),并生成可能省略的副本;直接初始化显式构造函数,直接构造目标。标准第8.5条规定:

14 - The form of initialization (using parentheses or =) is generally insignificant, but does matter when the initializer or the entity being initialized has a class type [...]

14 -初始化的形式(使用圆括号或=)通常是不重要的,但是当初始化器或被初始化的实体具有类类型[…]时,这一点很重要。

For non-class types (including references), direct-initialization and copy-initialization have similar semantics; for references, a reference binding occurs in either case, as specified in 8.5.3 References [dcl.init.ref]. Direct-initialization and copy-initialization of a reference only have different semantics where a conversion function is involved (13.3.1.6 Initialization by conversion function for direct reference binding [over.match.ref]); again, direct-initialization is allowed to invoke explicit conversion functions where copy-initialization is not.

对于非类类型(包括引用),直接初始化和复制初始化具有相似的语义;对于引用,在任何情况下都发生引用绑定,如8.5.3引用中所指定的那样。引用的直接初始化和复制初始化在涉及转换函数的地方只有不同的语义(13.3.1.6直接引用绑定的转换函数初始化[over.match.ref]);同样,允许直接初始化调用不包含复制初始化的显式转换函数。

So, in

所以,在

int &j = i;

8.5.3p5 applies and the reference j is bound directly to the lvalue i. No temporaries are invoked.

8.5.3p5适用,引用j直接绑定到lvalue i,不调用临时变量。

In terms of complexity, references are closer to fundamental (primitive) types than to class types. Primitives are initialized without a temporary being constructed (8.5p17, last bullet) and in general references are too. This is probably why the book only uses the = form for initialization of references; as with primitives, there is usually no difference and writing int i = x; is usually clearer than int i(x);.

就复杂性而言,引用更接近基本(基本)类型,而不是类类型。原语被初始化,而没有构造临时的(8.5p17,最后一颗子弹),一般的引用也被初始化。这可能就是为什么本书只使用=表单来初始化引用;与原语一样,通常没有区别,写int i = x;通常比int i(x)更清楚;

#2


4  

The terms copy-initialization and direct-initialization are part of the grammar of C++. they don't immediately tell you what sort of code generation happens. The meaning of any grammatical construction is described by the standard, and the context of initialization there are lots of different particular consequences depending on the types of the things that are being initialized.

术语复制初始化和直接初始化是c++语法的一部分。他们不会马上告诉你发生了什么类型的代码。任何语法结构的意义都由标准来描述,初始化的上下文根据被初始化的对象的类型有很多不同的特殊结果。

In particular, for primitive types, pointer types and reference types, both direct- and copy-initialization (the grammatical construct!) have the exact same effect. That is, fundamental and pointer types are initialized with the value of the initializer, and references are bound to the object referred to by the initializer:

特别是对于原始类型、指针类型和引用类型,直接初始化和复制初始化(语法结构!)都具有相同的效果。也就是说,用初始化器的值初始化基本类型和指针类型,引用被绑定到初始化器引用的对象:

int a1 = 5;
int a2(5);      // same thing

Foo * p1 = &x;
Foo * p2(&x);   // same thing

Bar & b1 = y;
Bar & b2(y);    // same thing

(However, for user-defined types there is a distinction between direct- and copy-initialization, although it is a subtle one that is usually not important.)

(不过,对于用户定义的类型,直接初始化和复制初始化之间有区别,尽管这是一个通常不重要的细微差别。)

#3


3  

A reference in C++ is just a pointer wearing a funny hat. The statement:

c++中的引用只是一个戴着滑稽帽子的指针。声明:

TYPE& x = y;

is always equivalent to:

总是相当于:

TYPE* const x = &y;

All references do is save you typing * characters and declare your belief that there will never be a null. So the initialization is trivial, since it is an initialization of a pointer, not an object, and there is no complexity of objects, temporary or otherwise, to deal with.

所有的引用都是保存您输入的*字符,并声明您认为永远不会有null。所以初始化是很简单的,因为它是一个指针的初始化,而不是一个对象,并且没有对象的复杂性,不管是临时的还是其他的。

This is the conceptual model; of course, there are optimizations. If you declare a function like:

这是概念模型;当然,还有优化。如果您声明一个函数,如:

void takeARef(FOO const& ref) { ... }

and call it, then the compiler is just going to pass a pointer into the function, and create nothing.

调用它,编译器就会向函数中传递一个指针,什么都不创建。

#1


6  

The main differences between direct-initialization and copy-initialization are covered in section 8.5, paragraph 17 of the standard. In general, the difference is that for class types in copy-initialization, explicit constructors are not considered (only converting constructors are considered) and a possibly elided copy is made; in direct-initialization explicit constructors are considered and the target is constructed directly. From section 8.5 of the standard:

直接初始化和复制初始化之间的主要区别载于标准第8.5节第17段。一般而言,不同之处在于,对于复制初始化中的类类型,不考虑显式构造函数(只考虑转换构造函数),并生成可能省略的副本;直接初始化显式构造函数,直接构造目标。标准第8.5条规定:

14 - The form of initialization (using parentheses or =) is generally insignificant, but does matter when the initializer or the entity being initialized has a class type [...]

14 -初始化的形式(使用圆括号或=)通常是不重要的,但是当初始化器或被初始化的实体具有类类型[…]时,这一点很重要。

For non-class types (including references), direct-initialization and copy-initialization have similar semantics; for references, a reference binding occurs in either case, as specified in 8.5.3 References [dcl.init.ref]. Direct-initialization and copy-initialization of a reference only have different semantics where a conversion function is involved (13.3.1.6 Initialization by conversion function for direct reference binding [over.match.ref]); again, direct-initialization is allowed to invoke explicit conversion functions where copy-initialization is not.

对于非类类型(包括引用),直接初始化和复制初始化具有相似的语义;对于引用,在任何情况下都发生引用绑定,如8.5.3引用中所指定的那样。引用的直接初始化和复制初始化在涉及转换函数的地方只有不同的语义(13.3.1.6直接引用绑定的转换函数初始化[over.match.ref]);同样,允许直接初始化调用不包含复制初始化的显式转换函数。

So, in

所以,在

int &j = i;

8.5.3p5 applies and the reference j is bound directly to the lvalue i. No temporaries are invoked.

8.5.3p5适用,引用j直接绑定到lvalue i,不调用临时变量。

In terms of complexity, references are closer to fundamental (primitive) types than to class types. Primitives are initialized without a temporary being constructed (8.5p17, last bullet) and in general references are too. This is probably why the book only uses the = form for initialization of references; as with primitives, there is usually no difference and writing int i = x; is usually clearer than int i(x);.

就复杂性而言,引用更接近基本(基本)类型,而不是类类型。原语被初始化,而没有构造临时的(8.5p17,最后一颗子弹),一般的引用也被初始化。这可能就是为什么本书只使用=表单来初始化引用;与原语一样,通常没有区别,写int i = x;通常比int i(x)更清楚;

#2


4  

The terms copy-initialization and direct-initialization are part of the grammar of C++. they don't immediately tell you what sort of code generation happens. The meaning of any grammatical construction is described by the standard, and the context of initialization there are lots of different particular consequences depending on the types of the things that are being initialized.

术语复制初始化和直接初始化是c++语法的一部分。他们不会马上告诉你发生了什么类型的代码。任何语法结构的意义都由标准来描述,初始化的上下文根据被初始化的对象的类型有很多不同的特殊结果。

In particular, for primitive types, pointer types and reference types, both direct- and copy-initialization (the grammatical construct!) have the exact same effect. That is, fundamental and pointer types are initialized with the value of the initializer, and references are bound to the object referred to by the initializer:

特别是对于原始类型、指针类型和引用类型,直接初始化和复制初始化(语法结构!)都具有相同的效果。也就是说,用初始化器的值初始化基本类型和指针类型,引用被绑定到初始化器引用的对象:

int a1 = 5;
int a2(5);      // same thing

Foo * p1 = &x;
Foo * p2(&x);   // same thing

Bar & b1 = y;
Bar & b2(y);    // same thing

(However, for user-defined types there is a distinction between direct- and copy-initialization, although it is a subtle one that is usually not important.)

(不过,对于用户定义的类型,直接初始化和复制初始化之间有区别,尽管这是一个通常不重要的细微差别。)

#3


3  

A reference in C++ is just a pointer wearing a funny hat. The statement:

c++中的引用只是一个戴着滑稽帽子的指针。声明:

TYPE& x = y;

is always equivalent to:

总是相当于:

TYPE* const x = &y;

All references do is save you typing * characters and declare your belief that there will never be a null. So the initialization is trivial, since it is an initialization of a pointer, not an object, and there is no complexity of objects, temporary or otherwise, to deal with.

所有的引用都是保存您输入的*字符,并声明您认为永远不会有null。所以初始化是很简单的,因为它是一个指针的初始化,而不是一个对象,并且没有对象的复杂性,不管是临时的还是其他的。

This is the conceptual model; of course, there are optimizations. If you declare a function like:

这是概念模型;当然,还有优化。如果您声明一个函数,如:

void takeARef(FOO const& ref) { ... }

and call it, then the compiler is just going to pass a pointer into the function, and create nothing.

调用它,编译器就会向函数中传递一个指针,什么都不创建。