brace-initialization
# brace initialization (using curly braces) 的好处
从 Bjarne Stroustrup's "The C++ Programming Language 4th Edition" 中有这样一段话:
List initialization does not allow narrowing (§iso.8.5.4). That is:
An integer cannot be converted to another integer that cannot hold its value. For example, char to int is allowed, but not int to char.
A floating-point value cannot be converted to another floating-point type that cannot hold its value. For example, float to double is allowed, but not double to float.
A floating-point value cannot be converted to an integer type.
An integer value cannot be converted to a floating-point type.
举例说明:
void fun(double val, int val2) {
int x2 = val; // if val == 7.9, x2 becomes 7 (bad)
char c2 = val2; // if val2 == 1025, c2 becomes 1 (bad)
int x3 {val}; // error: possible truncation (good)
char c3 {val2}; // error: possible narrowing (good)
char c4 {24}; // OK: 24 can be represented exactly as a char (good)
char c5 {264}; // error (assuming 8-bit chars): 264 cannot be
// represented as a char (good)
int x4 {2.0}; // error: no double to int value conversion (good)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
总结
总结来说,使用 brace 来进行初始化有利于避免因为类型转化而产生的错误。
参考资料:What are the advantages of list initialization (using curly braces)? (opens new window)
# Brace initialization for Class
- If a class or struct has no constructor, you provide the list elements in the order that the members are declared in the class.
class class_d {
public:
float m_float;
string m_string;
wchar_t m_char;
};
int main()
{
class_d d1{};
class_d d1{ 4.5 };
class_d d2{ 4.5, "string" };
class_d d3{ 4.5, "string", 'c' };
class_d d4{ "string", 'c' }; // compiler error
class_d d5{ "string", 'c', 2.0 }; // compiler error
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- If a type has a default constructor, either implicitly or explicitly declared, you can use brace initialization with empty braces to invoke it.
- If the class has a constructor, provide the elements in the order of the parameters.
#include <string>
using namespace std;
class class_a {
public:
class_a() {} // explicitly default consturctor
class_a(string str) : m_string{ str } {}
class_a(string str, double dbl) : m_string{ str }, m_double{ dbl } {}
double m_double;
string m_string;
};
int main()
{
class_a c1{};
class_a c1_1;
class_a c2{ "ww" };
class_a c2_1("xx");
// order of parameters is the same as the constructor
class_a c3{ "yy", 4.4 };
class_a c3_1("zz", 5.5);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
- If the default constructor is explicitly declared but marked as deleted, empty brace initialization can't be used:
class class_f {
public:
class_f() = delete;
class_f(string x): m_string { x } {}
string m_string;
};
int main()
{
class_f cf{ "hello" };
class_f cf1{}; // compiler error C2280: attempting to reference a deleted function
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
上次更新: 12/27/2023, 8:55:47 AM