list initialization
Initializes an object from braced-init-list
Contents[hide] |
[edit] Syntax
[edit] direct-list-initialization
T object { arg1, arg2, ... }; | (1) | ||||||||
T { arg1, arg2, ... }; | (2) | ||||||||
new T { arg1, arg2, ... } | (3) | ||||||||
Class { T member { arg1, arg2, ... }; }; | (4) | ||||||||
Class:: Class() : member{ arg1, arg2, ...} {... | (5) | ||||||||
[edit] copy-list-initialization
T object = { arg1, arg2, ...}; | (6) | ||||||||
function( { arg1, arg2, ... } ) ; | (7) | ||||||||
return { arg1, arg2, ... } ; | (8) | ||||||||
object[ { arg1, arg2, ... } ] ; | (9) | ||||||||
object = { arg1, arg2, ... } ; | (10) | ||||||||
U( { arg1, arg2, ... } ) | (11) | ||||||||
Class { T member = { arg1, arg2, ... }; }; | (12) | ||||||||
List initialization is performed in the following situations:
- direct-list-initialization (both explicit and non-explicit constructors are considered)
- copy-list-initialization (only non-explicit constructors may be called)
operator[]
, where list-initialization initializes the parameter of the overloaded operatoroperator=
[edit] Explanation
The effects of list initialization of an object of type T
are:
| (since C++14) |
| (until C++14) |
| (since C++14) |
- Otherwise, if
T
is a specialization of std::initializer_list, theT
object is direct-initialized or copy-initialized, depending on context, from a prvalue of the same time initialized from (until C++17) the braced-init-list.
- Otherwise, the constructors of
T
are considered, in two phases:
- All constructors that take std::initializer_list as the only argument, or as the first argument if the remaining arguments have default values, are examined, and matched by overload resolution against a single argument of type std::initializer_list
- If the previous stage does not produce a match, all constructors of
T
participate in overload resolution against the set of arguments that consists of the elements of the braced-init-list, with the restriction that only non-narrowing conversions are allowed. If this stage produces an explicit constructor as the best match for a copy-list-initialization, compilation fails (note, in simple copy-initialization, explicit constructors are not considered at all).
- If the previous stage does not produce a match, all constructors of
| (since C++17) |
- Otherwise (if
T
is not a class type), if the braced-init-list has only one element and eitherT
isn't a reference type or is a reference type that is compatible with the type of the element,T
is direct-initialized (in direct-list-initialization) or copy-initialized (in copy-list-initialization), except that narrowing conversions are not allowed.
- Otherwise, if
T
is a reference type that isn't compatible with the type of the element, a temporary of the referenced type is list-initialized, and the reference is bound to that temporary (until C++17)the reference is direct-initialized from a prvalue expression of the referenced type that list-initializes its result object (since C++17). (this fails if the reference is a non-const lvalue reference)
- Otherwise, if the braced-init-list has no elements,
T
is value-initialized.
[edit] Narrowing conversions
list-initialization limits the allowed implicit conversions by prohibiting the following:
- conversion from a floating-point type to an integer type
- conversion from a long double to double or to float and conversion from double to float, except where the source is a constant expression and overflow does not occur
- conversion from an integer type to a floating-point type, except where the source is a constant expression whose value can be stored exactly in the target type
- conversion from integer or unscoped enumeration type to integer type that cannot represent all values of the original, except where source is a constant expression whose value can be stored exactly in the target type
[edit] Notes
A braced-init-list is not an expression and therefore has no type, e.g. decltype({1,2}) is ill-formed. Having no type implies that template type deduction cannot deduce a type that matches a braced-init-list, so given the declaration template<class T> void f(T); the expression f({1,2,3}) is ill-formed. A special exception is made for type deduction using the keyword auto , which deduces any braced-init-list as std::initializer_list
Also because braced-init-list has no type, special rules for overload resolution apply when it is used as an argument to an overloaded function call.
Aggregates copy/move initialize directly from single-element braced-init-lists of the same type, but non-aggregates consider initializer_list constructors first: struct X { X() = default; X(const X&) = default; }; struct Q { Q() = default; Q(Q const&) = default; Q(std::initializer_list<Q>) {} }; int main() { X x; X x2 = X { x }; // copy-constructor (not aggregate initialization) Q q; Q q2 = Q { q }; // initializer-list constructor (not copy constructor) } | (since C++14) |
[edit] Example
#include <iostream>
#include <vector>
#include <map>
#include <string>
struct Foo {
std::vector<int> mem = {1,2,3}; // list-initialization of a non-static member
std::vector<int> mem2;
Foo() : mem2{-1, -2, -3} {} // list-initialization of a member in constructor
};
std::pair<std::string, std::string> f(std::pair<std::string, std::string> p)
{
return {p.second, p.first}; // list-initialization in return statement
}
int main()
{
int n0{}; // value-initialization (to zero)
int n1{1}; // direct-list-initialization
std::string s1{'a', 'b', 'c', 'd'}; // initializer-list constructor call
std::string s2{s1, 2, 2}; // regular constructor call
std::string s3{0x61, 'a'}; // initializer-list ctor is preferred to (int, char)
int n2 = {1}; // copy-list-initialization
double d = double{1.2}; // list-initialization of a temporary, then copy-init
std::map<int, std::string> m = { // nested list-initialization
{1, "a"},
{2, {'a', 'b', 'c'} },
{3, s1}
};
std::cout << f({"hello", "world"}).first // list-initialization in function call
<< '\n';
const int (&ar)[2] = {1,2}; // binds a lvalue reference to a temporary array
int&& r1 = {1}; // binds a rvalue reference to a temporary int
// int& r2 = {2}; // error: cannot bind rvalue to a non-const lvalue ref
// int bad{1.0}; // error: narrowing conversion
unsigned char uc1{10}; // okay
// unsigned char uc2{-1}; // error: narrowing conversion
Foo f;
std::cout << n0 << ' ' << n1 << ' ' << n2 << '\n'
<< s1 << ' ' << s2 << ' ' << s3 << '\n';
for(auto p: m)
std::cout << p.first << ' ' << p.second << '\n';
for(auto n: f.mem)
std::cout << n << ' ';
for(auto n: f.mem2)
std::cout << n << ' ';
}
Compiler messages:
main.cpp: In function 'int main()':
main.cpp:26:12: warning: unused variable 'd' [-Wunused-variable]
double d = double{1.2}; // list-initialization of a temporary, then copy-init
^
main.cpp:37:17: warning: unused variable 'ar' [-Wunused-variable]
const int (&ar)[2] = {1,2}; // binds a lvalue reference to a temporary array
^~
main.cpp:38:11: warning: unused variable 'r1' [-Wunused-variable]
int&& r1 = {1}; // binds a rvalue reference to a temporary int
^~
main.cpp:42:19: warning: unused variable 'uc1' [-Wunused-variable]
unsigned char uc1{10}; // okay
^~~
Output:
world
0 1 1
abcd cd aa
1 a
2 abc
3 abcd
1 2 3 -1 -2 -3
[edit] Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
CWG 1467 | C++14 | same-type initialization of aggregates and char arrays was prohibited | same-type initialization allowed |
CWG 1467 | C++14 | std::initializer_list constructors had priority over copy constructors for single-element lists | single-element lists initialize directly |
[edit] See also
相關文章
- Initialization
- The SPFILE Initialization Parameter
- 初始化 (Initialization)
- Special Characters in Initialization Parameter Files
- SKIP_UNUSABLE_INDEXES InitializationIndex
- OPTIMIZER_MODE Initialization Parameter
- Understanding Initialization Parameters (85)
- Other SGA Initialization Parameters (96)
- [VRDevice] Initialization of device oculus failed.VRdevAI
- Rules Governing Initialization Parameter FilesGo
- DB_NAME Initialization Parameter (87)
- DB_DOMAIN Initialization Parameter (88)AI
- The SGA_TARGET Initialization Parameter (74)
- Talking about Android Initialization ProcessAndroid
- Initialization Parameter Files and Server Parameter Files (287)Server
- Step 3: Create the Initialization Parameter File (61)
- DB_BLOCK_SIZE Initialization Parameter (92)BloC
- The SGA_MAX_SIZE Initialization Parameter (72)
- Entity Framework Code-First(6):Database InitializationFrameworkDatabase
- UNDO_MANAGEMENT Initialization Parameter (118)
- WPF initialization for opening and unitialization for closing process
- C# List 用法list<>C#
- Initialization of bean failed; nested exception is java.lang.StackOverflowErrorBeanAIExceptionJavaError
- Entity Framework Code-First(17):Database Initialization StrategyFrameworkDatabase
- Powercenter8.1.1之啟動Service initialization failedAI
- RMAN-00554: initialization of internal recovery manager package failedPackageAI
- Setting the Buffer Cache Initialization Parameters (108)
- DB_CACHE_SIZE Initialization Parameter (109)
- Python List 列表list()方法Python
- list
- Hql總結 查詢結果動態組裝成List(map),List(bean),List(list),List(set)等格式(轉)Bean
- Python List 列表list()方法分享Python
- Swift中Initialization的一些個人總結Swift
- device eth0 does not seem to be present, delaying initializationdev
- failure in css initialization opening OCR 問題處理AICSS
- The DB_nK_CACHE_SIZE Initialization Parameters (110)
- Initialization Parameter Changes from 9i to 10g
- int[] 、 list<int> 、 list<int>[] 的區別