Is there any difference between
两者之间有什么区别吗?
std::string s1("foo");
and
std::string s2 = "foo";
?
4 个解决方案
#1
27
Yes and No.
是和否。
The first is initialized explicitly, and the second is copy initialized. The standards permits to replace the second with the first. In practice, the produced code is the same.
第一个是显式初始化,第二个是初始化的复制。标准允许用第一个替换第二个。实际上,生成的代码是相同的。
Here is what happens in a nutshell:
简而言之,这就是:
std::string s1("foo");
The string constructor of the form:
表单的字符串构造函数:
string ( const char * s );
is called for s1
.
被称为s1。
In the second case. A temporary is created, and the mentioned earler constructor is called for that temporary. Then, the copy constructor is invoked. e.g:
在第二种情况下。创建一个临时文件,并为该临时文件调用所提到的earler构造函数。然后,调用复制构造函数。例如:
string s1 = string("foo");
In practice, the second form is optimized, to be of the form of the first. I haven't seen a compiler that doesn't optimize the second case.
在实践中,第二种形式被优化,成为第一种形式。我没有看到没有优化第二种情况的编译器。
#2
13
On the face of it, the first one calls the const char*
constructor to initialize s1
. The second one uses the const char*
constructor to initialize a temporary value, and then uses the copy constructor, passing in a reference to that temporary value, to initialize s2
.
从表面上看,第一个调用const char *构造函数来初始化s1。第二个使用const char *构造函数初始化临时值,然后使用复制构造函数,传入对该临时值的引用,以初始化s2。
However, the standard explicitly permits something called "copy elision", which means that as AraK says, the second can legally be replaced with the first even if the copy constructor has observable side-effects, so that the change affects the output of the program.
但是,标准明确允许称为“复制省略”的东西,这意味着正如AraK所说,即使复制构造函数具有可观察的副作用,第二个也可以合法地替换为第一个,因此更改会影响程序的输出。
However, when this replacement is done, the compiler must still check that the class has an accessible copy constructor. So a potential difference is that the second form requires a copy constructor to be callable, even though the compiler doesn't have to call it. Obviously std::string
does have one, so in this case that doesn't make a difference, but for other classes it could.
但是,当完成此替换时,编译器仍必须检查该类是否具有可访问的复制构造函数。因此,潜在的区别在于第二种形式需要复制构造函数可调用,即使编译器不必调用它。显然std :: string确实有一个,所以在这种情况下,这没有什么区别,但对于其他类,它可以。
#3
3
there's no difference
没有区别
#4
-5
The first one is better.
第一个更好。
The second one will create the instance and will assign the default value (""). Then there will be a secodn assignement : "foo". So 2 assignments instead of 1...
第二个将创建实例并将分配默认值(“”)。然后会有一个secodn assignement:“foo”。所以2个作业而不是1 ...
#1
27
Yes and No.
是和否。
The first is initialized explicitly, and the second is copy initialized. The standards permits to replace the second with the first. In practice, the produced code is the same.
第一个是显式初始化,第二个是初始化的复制。标准允许用第一个替换第二个。实际上,生成的代码是相同的。
Here is what happens in a nutshell:
简而言之,这就是:
std::string s1("foo");
The string constructor of the form:
表单的字符串构造函数:
string ( const char * s );
is called for s1
.
被称为s1。
In the second case. A temporary is created, and the mentioned earler constructor is called for that temporary. Then, the copy constructor is invoked. e.g:
在第二种情况下。创建一个临时文件,并为该临时文件调用所提到的earler构造函数。然后,调用复制构造函数。例如:
string s1 = string("foo");
In practice, the second form is optimized, to be of the form of the first. I haven't seen a compiler that doesn't optimize the second case.
在实践中,第二种形式被优化,成为第一种形式。我没有看到没有优化第二种情况的编译器。
#2
13
On the face of it, the first one calls the const char*
constructor to initialize s1
. The second one uses the const char*
constructor to initialize a temporary value, and then uses the copy constructor, passing in a reference to that temporary value, to initialize s2
.
从表面上看,第一个调用const char *构造函数来初始化s1。第二个使用const char *构造函数初始化临时值,然后使用复制构造函数,传入对该临时值的引用,以初始化s2。
However, the standard explicitly permits something called "copy elision", which means that as AraK says, the second can legally be replaced with the first even if the copy constructor has observable side-effects, so that the change affects the output of the program.
但是,标准明确允许称为“复制省略”的东西,这意味着正如AraK所说,即使复制构造函数具有可观察的副作用,第二个也可以合法地替换为第一个,因此更改会影响程序的输出。
However, when this replacement is done, the compiler must still check that the class has an accessible copy constructor. So a potential difference is that the second form requires a copy constructor to be callable, even though the compiler doesn't have to call it. Obviously std::string
does have one, so in this case that doesn't make a difference, but for other classes it could.
但是,当完成此替换时,编译器仍必须检查该类是否具有可访问的复制构造函数。因此,潜在的区别在于第二种形式需要复制构造函数可调用,即使编译器不必调用它。显然std :: string确实有一个,所以在这种情况下,这没有什么区别,但对于其他类,它可以。
#3
3
there's no difference
没有区别
#4
-5
The first one is better.
第一个更好。
The second one will create the instance and will assign the default value (""). Then there will be a secodn assignement : "foo". So 2 assignments instead of 1...
第二个将创建实例并将分配默认值(“”)。然后会有一个secodn assignement:“foo”。所以2个作业而不是1 ...