Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Direct-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 explicit set of constructor arguments.

      Contents

      [edit]Syntax

      Tobject(arg);

      Tobject(arg1, arg2, ...);

      (1)
      Tobject{arg}; (2)(since C++11)
      T(other)

      T(arg1, arg2, ...)

      (3)
      static_cast<T>(other) (4)
      newT(args, ...) (5)
      Class::Class():member(args, ...){...} (6)
      [arg]() {...} (7)(since C++11)

      [edit]Explanation

      Direct-initialization is performed in the following situations:

      1) Initialization with a nonempty parenthesized list of expressionsor braced-init-lists(since C++11).
      2) Initialization of an object of non-class type with a single brace-enclosed initializer(note: for class types and other uses of braced-init-list, seelist-initialization)(since C++11).
      3) Initialization ofa prvalue temporary(until C++17)the result object of a prvalue(since C++17) byfunction-style cast or with a parenthesized expression list.
      4) Initialization ofa prvalue temporary(until C++17)the result object of a prvalue(since C++17) by astatic_cast expression.
      5) Initialization of an object with dynamic storage duration by a new-expression with an initializer.
      6) Initialization of a base or a non-static member by constructorinitializer list.
      7) Initialization of closure object members from the variables caught by copy in a lambda-expression.

      The effects of direct-initialization are:

      • IfT is an array type,
      • the program is ill-formed.
      (until C++20)
      struct A{explicit A(int i=0){}}; A a[2](A(1));// OK: initializes a[0] with A(1) and a[1] with A()A b[2]{A(1)};// error: implicit copy-list-initialization of b[1]//        from {} selected explicit constructor
      (since C++20)
      • IfT is a class type,
      • if the initializer is aprvalue expression whose type is the same class asT (ignoring cv-qualification), the initializer expression itself, rather than a temporary materialized from it, is used to initialize the destination object.
        (Before C++17, the compiler may elide the construction from the prvalue temporary in this case, but the appropriate constructor must still be accessible: seecopy elision)
      (since C++17)
      • the constructors ofT are examined and the best match is selected by overload resolution. The constructor is then called to initialize the object.
      • otherwise, if the destination type is a (possibly cv-qualified) aggregate class, it is initialized as described inaggregate initialization except that narrowing conversions are permitted, designated initializers are not allowed, a temporary bound to a reference does not have its lifetime extended, there is no brace elision, and any elements without an initializer arevalue-initialized.
      struct B{int a;int&& r;}; int f();int n=10; B b1{1, f()};// OK, lifetime is extendedB b2(1, f());// well-formed, but dangling referenceB b3{1.0,1};// error: narrowing conversionB b4(1.0,1);// well-formed, but dangling referenceB b5(1.0, std::move(n));// OK
      (since C++20)
      • Otherwise, ifT is a non-class type but the source type is a class type, the conversion functions of the source type and its base classes, if any, are examined and the best match is selected by overload resolution. The selected user-defined conversion is then used to convert the initializer expression into the object being initialized.
      • Otherwise, ifT isbool and the source type isstd::nullptr_t, the value of the initialized object isfalse.
      • Otherwise,standard conversions are used, if necessary, to convert the value ofother to the cv-unqualified version ofT, and the initial value of the object being initialized is the (possibly converted) value.

      [edit]Notes

      Direct-initialization is more permissive than copy-initialization: copy-initialization only considers non-explicit constructors and non-explicit user-definedconversion functions, while direct-initialization considers all constructors and all user-defined conversion functions.

      In case of ambiguity between a variable declaration using the direct-initialization syntax(1) (with round parentheses) and afunction declaration, the compiler always chooses function declaration. This disambiguation rule is sometimes counter-intuitive and has been called themost vexing parse.

      Run this code
      #include <fstream>#include <iterator>#include <string> int main(){std::ifstream file("data.txt"); // The following is a function declaration:std::string foo1(std::istreambuf_iterator<char>(file),std::istreambuf_iterator<char>());// It declares a function called foo1, whose return type is std::string,// first parameter has type std::istreambuf_iterator<char> and the name "file",// second parameter has no name and has type std::istreambuf_iterator<char>(),// which is rewritten to function pointer type std::istreambuf_iterator<char>(*)() // Pre-C++11 fix (to declare a variable) - add extra parentheses around one// of the arguments:std::string str1((std::istreambuf_iterator<char>(file)),std::istreambuf_iterator<char>()); // Post-C++11 fix (to declare a variable) - use list-initialization for any// of the arguments:std::string str2(std::istreambuf_iterator<char>{file},{});}

      [edit]Example

      Run this code
      #include <iostream>#include <memory>#include <string> struct Foo{int mem;explicit Foo(int n): mem(n){}}; int main(){std::string s1("test");// constructor from const char*std::string s2(10,'a'); std::unique_ptr<int> p(newint(1));// OK: explicit constructors allowed//  std::unique_ptr<int> p = new int(1); // error: constructor is explicit     Foo f(2);// f is direct-initialized:// constructor parameter n is copy-initialized from the rvalue 2// f.mem is direct-initialized from the parameter n//  Foo f2 = 2; // error: constructor is explicit std::cout<< s1<<' '<< s2<<' '<<*p<<' '<< f.mem<<'\n';}

      Output:

      test aaaaaaaaaa 1 2

      [edit]See also

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

      [8]ページ先頭

      ©2009-2025 Movatter.jp