copy initialization
复制初始化
从另一个对象初始化对象。
句法
T object = other; | (1) | |
---|---|---|
T object = {other} ; | (2) | (until C++11) |
f(other) | (3) | |
return other; | (4) | |
throw object; catch (T object). | (5) | |
T arrayN = {other}; | (6) | |
解释
在下列情况下执行副本初始化:
1%29当非引用类型的命名变量%28自动、静态或线程本地%29时T
是使用包含一个等于符号和一个表达式的初始化器声明的。
2%29%28直到C++11%29,当标量类型的命名变量T
声明时,初始化器由一个等于符号和一个大括号括起来的表达式%28Note组成:从C++11开始,这被归类为列表初始化,并且不允许缩小转换%29。
3%29传递论点按值计算为函数
4%29回归从按值返回的函数
5%29投掷或抓到按值计算的例外
6%29聚合初始化,以初始化提供初始化程序的每个元素。
副本初始化的效果如下:
First, if T is a class type and the initializer is a prvalue expression whose cv-unqualified type is the same class as T, the initializer expression itself, rather that a temporary materialized from it, is used to initialize the destination object: see copy elision | (since C++17) |
---|
- 首先,如果
T
是类类型,初始化器是prvalue表达式,其cv-不限定类型与T
,初始化器表达式本身,而不是从它得到的临时物化,用于初始化目标对象:复制省略%28自C++17%29
- 如果
T
是类类型,其他类型的cv-不限定版本是T
或派生自T
,非显式构造函数成T
并通过过载解析选择最佳匹配。然后调用构造函数来初始化对象。
- 如果
T
是类类型,而其他类型的cv-不限定版本不是。T
或衍生自T
,或者如果T
是非类类型,但其他类型是类类型,用户定义的转换序列可以将其他类型转换为T
%28或从T
派生的类型(如果T
是类类型并可用的转换函数),检查%29,并通过过载解析选择最佳的类型。转换的结果,它是一个prvalue临时%28,直到C++17%29 prvalue表达式%28,因为C++17%29如果转换构造函数被使用,然后习惯于直接初始化物体。最后一步通常是优化出转换的结果直接在分配给目标对象的内存中构造,但是即使不使用%27,也需要适当的构造函数%28 Move或Copy%29才能访问。%28直到C++17%29
- 否则,%28,如果两者都没有
T
也不是其他类型的类类型%29,标准转换的值转换为T
...
注记
复制初始化不像直接初始化那样允许:显式构造函数不是转换构造函数并且不考虑复制初始化。
二次
struct Exp { explicit Exp(const char*) {} }; // not convertible from const char*
Exp e1("abc" // OK
Exp e2 = "abc"; // Error, copy-initialization does not consider explicit constructor
struct Imp { Imp(const char*) {} }; // convertible from const char*
Imp i1("abc" // OK
Imp i2 = "abc"; // OK
二次
此外,复制初始化中的隐式转换必须生成。T
直接从初始化项,而直接初始化则期望从初始化程序到参数的隐式转换。T
%27s构造函数
二次
struct S { S(std::string) {} }; // implicitly convertible from std::string
S s("abc" // OK: conversion from const char[4] to std::string
S s = "abc"; // Error: no conversion from const char[4] to S
S s = "abc"s; // OK: conversion from std::string to S
二次
如果其他是rvalue表达式,移动构造函数将通过重载解析选择并在复制初始化期间调用。没有移动初始化这样的术语。
隐式转换定义为复制初始化:如果类型为T
可以使用表达式进行复制初始化。E
,然后E
隐式可转换为T
...
等号,=
,在命名变量的复制初始化中,与赋值运算符无关。赋值运算符重载对复制初始化没有影响.
例
二次
#include <string>
#include <utility>
#include <memory>
int main()
{
std::string s = "test"; // OK: constructor is non-explicit
std::string s2 = std::move(s // this copy-initialization performs a move
// std::unique_ptr<int> p = new int(1 // error: constructor is explicit
std::unique_ptr<int> p(new int(1) // OK: direct-initialization
int n = 3.14; // floating-integral conversion
const int b = n; // const doesn't matter
int c = b; // ...either way
}
二次
另见
- 默认初始化
- 直接初始化
- 聚合初始化
- 列表初始化
© cppreference.com
在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。