Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/language/copy initialization"

From cppreference.com
< cpp‎ | language
(link to implicit conversion)
m (Shorten template names. Use {{lc}} where appropriate.)
Line 5: Line 5:
 
===Syntax===
 
===Syntax===
  
{{sdcl list begin}}
+
{{sdsc begin}}
{{sdcl list item | num=1 | {{sparam|T}} {{sparam| object}} {{ttb|{{=}} }} {{sparam|other}} {{ttb|;}} }}
+
{{sdsc | num=1 | {{spar|T}} {{spar| object}} {{ttb|{{=}} }} {{spar|other}} {{ttb|;}} }}
{{sdcl list item | num=2 | {{sparam|f}}{{ttb|(}}{{sparam|other}}{{ttb|)}}{{ttb|;}} }}
+
{{sdsc | num=2 | {{spar|f}}{{ttb|(}}{{spar|other}}{{ttb|)}}{{ttb|;}} }}
{{sdcl list item | num=3 | {{ttb|return }} {{sparam|other}}{{ttb|;}} }}
+
{{sdsc | num=3 | {{ttb|return }} {{spar|other}}{{ttb|;}} }}
{{sdcl list item | num=4 | {{ttb|catch (}} {{sparam|T}} {{sparam|other}}{{ttb|) ;}} }}
+
{{sdsc | num=4 | {{ttb|catch (}} {{spar|T}} {{spar|other}}{{ttb|) ;}} }}
{{sdcl list item | num=5 | {{sparam|T}} {{sparam|array}} {{ttb|[}} {{sparam|N}} {{ttb|] {{=}} { }} {{sparam|other}} {{ttb|};}}}}
+
{{sdsc | num=5 | {{spar|T}} {{spar|array}} {{ttb|[}} {{spar|N}} {{ttb|] {{=}} { }} {{spar|other}} {{ttb|};}}}}
{{sdcl list end}}
+
{{sdsc end}}
  
 
===Explanation===
 
===Explanation===
Line 24: Line 24:
 
The effects of copy initialization are:
 
The effects of copy initialization are:
  
* If {{tt|T}} is a class type and the type of {{sparam|other}} is cv-unqualified version of {{tt|T}} or a class derived from {{tt|T}}, the constructors of {{tt|T}} are examined and the best match is selected by overload resolution. The constructor is then called to initialize the object.
+
* If {{tt|T}} is a class type and the type of {{spar|other}} is cv-unqualified version of {{tt|T}} or a class derived from {{tt|T}}, the constructors of {{tt|T}} are examined and the best match is selected by overload resolution. The constructor is then called to initialize the object.
  
* If {{tt|T}} is a class type, and the type of {{sparam|other}} is different, or if {{tt|T}} is non-class type, but the type of {{sparam|other}} is a class type, [[cpp/language/implicit_cast|user-defined conversion sequences]] that can convert from the type of {{sparam|other}} to {{tt|T}} are examined and the best one is selected through overload resolution. The result of the conversion, which is a prvalue temporary of the destination type, is then used to [[cpp/language/direct_initialization|direct-initialize]] the object. The last step is usually [[cpp/language/copy_elision|eliminated]] and the result of the conversion function is constructed directly in the memory allocated for the target object, but the copy constructor is required to be accessible even though it's not used.
+
* If {{tt|T}} is a class type, and the type of {{spar|other}} is different, or if {{tt|T}} is non-class type, but the type of {{spar|other}} is a class type, [[cpp/language/implicit_cast|user-defined conversion sequences]] that can convert from the type of {{spar|other}} to {{tt|T}} are examined and the best one is selected through overload resolution. The result of the conversion, which is a prvalue temporary of the destination type, is then used to [[cpp/language/direct_initialization|direct-initialize]] the object. The last step is usually [[cpp/language/copy_elision|eliminated]] and the result of the conversion function is constructed directly in the memory allocated for the target object, but the copy constructor is required to be accessible even though it's not used.
  
* Otherwise (if neither {{tt|T}} nor the type of {{sparam|other}} are class types), [[cpp/language/implicit_cast|standard conversions]] are used, if necessary, to convert the value of {{sparam|other}} to the cv-unqualified version of {{tt|T}}.
+
* Otherwise (if neither {{tt|T}} nor the type of {{spar|other}} are class types), [[cpp/language/implicit_cast|standard conversions]] are used, if necessary, to convert the value of {{spar|other}} to the cv-unqualified version of {{tt|T}}.
  
 
===Notes===
 
===Notes===
 
Copy-initialization is less permissive than direct-initialization: copy-initialization only considers non-explicit constructors and user-defined conversion functions.
 
Copy-initialization is less permissive than direct-initialization: copy-initialization only considers non-explicit constructors and user-defined conversion functions.
  
If {{sparam|other}} is an rvalue expression, [[cpp/language/move_constructor|move constructor]] will be selected by overload resolution and called during copy-initialization.
+
If {{spar|other}} is an rvalue expression, [[cpp/language/move_constructor|move constructor]] will be selected by overload resolution and called during copy-initialization.
  
 
[[cpp/language/implicit_cast|Implicit conversion]] is defined in terms of copy-initialization: if an object of type {{tt|T}} can be copy-initialized with expression {{tt|E}}, then {{tt|E}} is implicitly convertible to {{tt|T}}.
 
[[cpp/language/implicit_cast|Implicit conversion]] is defined in terms of copy-initialization: if an object of type {{tt|T}} can be copy-initialized with expression {{tt|E}}, then {{tt|E}} is implicitly convertible to {{tt|T}}.

Revision as of 19:03, 31 May 2013

 
 
C++ language
General topics
Flow control
Conditional execution statements
if
Iteration statements (loops)
for
range-for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications (until C++17*)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
explicit (C++11)
static

Special member functions
Templates
Miscellaneous
 

Initializes an object from another object

Contents

Syntax

T object = other ; (1)
f(other); (2)
return other; (3)
catch ( T other) ; (4)
T array [ N ] = { other }; (5)

Explanation

Copy initialization is performed in the following situations:

1) when a named variable (automatic, static, or thread-local) is declared with the initializer consisting of an equals sign followed by an expression.
2) when passing an argument to a function by value
3) when returning from a function that returns by value
4) when catching an exception by value
5) as part of aggregate initialization, to initialize each element for which an initializer is provided

The effects of copy initialization are:

  • If T is a class type and the type of other is cv-unqualified version of T or a class derived from T, the constructors of T are examined and the best match is selected by overload resolution. The constructor is then called to initialize the object.
  • If T is a class type, and the type of other is different, or if T is non-class type, but the type of other is a class type, user-defined conversion sequences that can convert from the type of other to T are examined and the best one is selected through overload resolution. The result of the conversion, which is a prvalue temporary of the destination type, is then used to direct-initialize the object. The last step is usually eliminated and the result of the conversion function is constructed directly in the memory allocated for the target object, but the copy constructor is required to be accessible even though it's not used.
  • Otherwise (if neither T nor the type of other are class types), standard conversions are used, if necessary, to convert the value of other to the cv-unqualified version of T.

Notes

Copy-initialization is less permissive than direct-initialization: copy-initialization only considers non-explicit constructors and user-defined conversion functions.

If other is an rvalue expression, move constructor will be selected by overload resolution and called during copy-initialization.

Implicit conversion is defined in terms of copy-initialization: if an object of type T can be copy-initialized with expression E, then E is implicitly convertible to T.

The equals sign, =, in copy-initialization of a named variable is not related to the assignment operator. Assignment operator overloads have no effect on copy-initialization.

Example

#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
}

See also