Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Copy-initialization

      From cppreference.com
      <cpp‎ |language
       
       
      C++ language
      General topics
      Flow control
      Conditional execution statements
      Iteration statements (loops)
      Jump statements
      Functions
      Function declaration
      Lambda function expression
      inline specifier
      Dynamic exception specifications(until C++17*)
      noexcept specifier(C++11)
      Exceptions
      Namespaces
      Types
      Specifiers
      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
      Special member functions
      Templates
      Miscellaneous
       
       

      Initializes an object from another object.

      Contents

      [edit]Syntax

      Tobject=other; (1)
      Tobject={other}; (2)(until C++11)
      f(other) (3)
      returnother; (4)
      throwobject;

      catch (Tobject)

      (5)
      Tarray[N] = {other-sequence}; (6)

      [edit]Explanation

      Copy-initialization is performed in the following situations:

      1) When a named variable (automatic, static, or thread-local) of a non-reference typeT is declared with the initializer consisting of an equals sign followed by an expression.
      2)(until C++11) When a named variable of a scalar typeT is declared with the initializer consisting of an equals sign followed by a brace-enclosed expression (Note: as of C++11, this is classified aslist initialization, and narrowing conversion is not allowed).
      3) Whenpassing an argument to a function by value.
      4) Whenreturning from a function that returns by value.
      5) Whenthrowing orcatching an exception by value.
      6) As part ofaggregate initialization, to initialize each element for which an initializer is provided.

      The effects of copy-initialization are:

      • First, ifT is a class type and the initializer is aprvalue expression whose cv-unqualified type is the same class asT, the initializer expression itself, rather than a temporary materialized from it, is used to initialize the destination object: seecopy elision.
      (since C++17)
      • First(until C++17)Otherwise(since C++17), ifT is a class type and the cv-unqualified version of the type ofother isT or a class derived fromT, thenon-explicit constructors ofT are examined and the best match is selected by overload resolution. That constructor is then called to initialize the object.
      • Otherwise, ifT is a class type, and the cv-unqualified version of the type ofother is notT or derived fromT, or ifT is non-class type, but the type ofother is a class type,user-defined conversion sequences that can convert from the type ofother toT (or to a type derived fromT ifT is a class type and a conversion function is available) are examined and the best one is selected through overload resolution. The result of the conversion, which is arvalue temporary(until C++11)prvalue temporary(since C++11)(until C++17)prvalue expression(since C++17) of the cv-unqualified version ofT if aconverting constructor was used, is then used todirect-initialize the object.The last step is usuallyoptimized out and the result of the conversion is constructed directly in the memory allocated for the target object, but the appropriate constructor (move or copy) is required to be accessible even though it's not used.(until C++17)
      • Otherwise (if neitherT nor the type ofother are class types),standard conversions are used, if necessary, to convert the value ofother to the cv-unqualified version ofT.

      [edit]Notes

      Copy-initialization is less permissive than direct-initialization:explicit constructors are notconverting constructors and are not considered for copy-initialization.

      struct Exp{explicit Exp(constchar*){}};// not convertible from const char*Exp e1("abc");// OKExp e2="abc";// Error, copy-initialization does not consider explicit constructor struct Imp{ Imp(constchar*){}};// convertible from const char*Imp i1("abc");// OKImp i2="abc";// OK

      In addition, the implicit conversion in copy-initialization must produceT directly from the initializer, while, e.g. direct-initialization expects an implicit conversion from the initializer to an argument ofT's constructor.

      struct S{ S(std::string){}};// implicitly convertible from std::stringS s("abc");// OK: conversion from const char[4] to std::stringS s="abc";// Error: no conversion from const char[4] to SS s="abc"s;// OK: conversion from std::string to S

      Ifother is an rvalue expression, amove constructor will be selected by overload resolution and called during copy-initialization. This is still considered copy-initialization; there is no special term (e.g., move-initialization) for this case.

      Implicit conversion is defined in terms of copy-initialization: if an object of typeT can be copy-initialized with expressionE, thenE is implicitly convertible toT.

      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.

      [edit]Example

      Run this code
      #include <memory>#include <string>#include <utility> struct A{    operatorint(){return12;}}; struct B{    B(int){}}; int main(){std::string s="test";// OK: constructor is non-explicitstd::string s2= std::move(s);// this copy-initialization performs a move //  std::unique_ptr<int> p = new int(1); // error: constructor is explicitstd::unique_ptr<int> p(newint(1));// OK: direct-initialization int n=3.14;// floating-integral conversionconstint b= n;// const doesn't matterint c= b;// ...either way     A a;    B b0=12;//  B b1 = a;       // < error: conversion from 'A' to non-scalar type 'B' requested    B b2{a};// < identical, calling A::operator int(), then B::B(int)    B b3={a};// <auto b4= B{a};// < //  b0 = a;         // < error, assignment operator overload needed [](...){}(c, b0, b3, b4);// pretend these variables are used}

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      CWG 5C++98the cv-qualification of the destination type is applied to
      the temporary initialized by a converting constructor
      the temporary is not cv-qualified
      CWG 177C++98the value category of the temporary created during
      copy-initialization of a class object is unspecified
      specified as rvalue

      [edit]See also

      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/copy_initialization&oldid=183251"

      [8]ページ先頭

      ©2009-2025 Movatter.jp