a small fix

This commit is contained in:
猫耳堀川雷鼓 2021-02-02 21:09:07 +08:00 committed by GitHub
parent 933dd27182
commit d4bbc7bf05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -72,7 +72,7 @@ int sum2(x + y +z); //可以表达式的值被截为int
int sum3 = x + y + z; //同上
````
另一个值得注意的特性是括号表达式对于C++最令人头疼的解析问题有天生的免疫性。(译注:所谓最令人头疼的解析即_most vexing parse_,更多信息请参见[https://en.wikipedia.org/wiki/Most_vexing_parse](https://en.wikipedia.org/wiki/Most_vexing_parse)。C++规定任何能被决议为一个声明的东西必须被决议为声明。这个规则的副作用是让很多程序员备受折磨:当他们想创建一个使用默认构造函数构造的对象,却不小心变成了函数声明。问题的根源是如果你想使用一个实参调用一个构造函数,你可以这样做:
另一个值得注意的特性是括号表达式对于C++最令人头疼的解析问题有天生的免疫性。(译注:所谓最令人头疼的解析即*most vexing parse*,更多信息请参见[https://en.wikipedia.org/wiki/Most_vexing_parse](https://en.wikipedia.org/wiki/Most_vexing_parse)。C++规定任何能被决议为一个声明的东西必须被决议为声明。这个规则的副作用是让很多程序员备受折磨:当他们想创建一个使用默认构造函数构造的对象,却不小心变成了函数声明。问题的根源是如果你想使用一个实参调用一个构造函数,你可以这样做:
````cpp
Widget w1(10); //使用实参10调用Widget的一个构造函数
@ -153,10 +153,10 @@ Widget w8{std::move(w4)}; //使用花括号调用std::initializer_list构造
编译器热衷于把括号初始化与使`std::initializer_list`构造函数匹配了,尽管最佳匹配`std::initializer_list`构造函数不能被调用也会凑上去。比如:
````cpp
class Widget {
public:
Widget(int i, bool b); //同之前一样
Widget(int i, double d); //同之前一样
Widget(std::initializer_list<bool> il); //现在元素类型为bool
public:
Widget(int i, bool b); //同之前一样
Widget(int i, double d); //同之前一样
Widget(std::initializer_list<bool> il); //现在元素类型为bool
... //没有隐式转换函数
};
@ -169,11 +169,11 @@ Widget w{10, 5.0}; //错误!要求变窄转换
````cpp
class Widget {
public:
Widget(int i, bool b); //同之前一样
Widget(int i, double d); //同之前一样
//现在std::initializer_list元素类型为std::string
Widget(int i, bool b); //同之前一样
Widget(int i, double d); //同之前一样
//现在std::initializer_list元素类型为std::string
Widget(std::initializer_list<std::string> il);
... //没有隐式转换函数
... //没有隐式转换函数
};
Widget w1(10, true); // 使用小括号初始化,调用第一个构造函数
@ -187,10 +187,10 @@ Widget w4{10, 5.0}; // 使用花括号初始化,现在调用第二个构
````cpp
class Widget {
public:
Widget(); //默认构造函数
Widget(); //默认构造函数
Widget(std::initializer_list<int> il); //std::initializer_list构造函数
... //没有隐式转换函数
... //没有隐式转换函数
};
Widget w1; //调用默认构造函数
@ -242,8 +242,7 @@ doSomeWork<std::vector<int>>(10, 20);
````
如果`doSomeWork`创建`localObject`时使用的是小括号,`std::vector`就会包含10个元素。如果`doSomeWork`创建`localObject`时使用的是花括号,`std::vector`就会包含2个元素。哪个是正确的`doSomeWork`的作者不知道,只有调用者知道。
这正是标准库函数`std::make_unique`和`std::make_shared`(参见[Item21](https://github.com/kelthuzadx/EffectiveModernCppChinese/blob/master/4.SmartPointers/item21.md))面对的问题。它们的解决方案是使用小括号,并被记录在文档中作为接口的一部分。(注:更灵活的设计——允许调用者决定从模板来的函数应该使用小括号还是花括号——是有可能的。详情参见[Andrzejs C++
blog](http://akrzemi1.wordpress.com/)在2013年6月5日的文章“[Intuitive interface — Part I.](http://akrzemi1.wordpress.com/2013/06/05/intuitive-interface-part-i/)”)
这正是标准库函数`std::make_unique`和`std::make_shared`(参见[Item21](https://github.com/kelthuzadx/EffectiveModernCppChinese/blob/master/4.SmartPointers/item21.md))面对的问题。它们的解决方案是使用小括号,并被记录在文档中作为接口的一部分。(注:更灵活的设计——允许调用者决定从模板来的函数应该使用小括号还是花括号——是有可能的。详情参见[Andrzejs C++ blog](http://akrzemi1.wordpress.com/)在2013年6月5日的文章“[Intuitive interface — Part I.](http://akrzemi1.wordpress.com/2013/06/05/intuitive-interface-part-i/)”)
**请记住:**