mirror of
https://github.com/CnTransGroup/EffectiveModernCppChinese.git
synced 2025-01-01 07:50:15 +08:00
deploy: a2296112ea
This commit is contained in:
parent
0919dc53c3
commit
a764979a18
@ -316,8 +316,8 @@ std::vector<int> v2{10, 20}; //使用std::initializer_list构造函数
|
||||
</code></pre>
|
||||
<p>让我们退回之前的讨论。从这个讨论中我有两个重要结论。第一,作为一个类库作者,你需要意识到如果你的一堆重载的构造函数中有一个或者多个含有<code>std::initializer_list</code>形参,用户代码如果使用了括号初始化,可能只会看到你<code>std::initializer_list</code>版本的重载的构造函数。因此,你最好把你的构造函数设计为不管用户是小括号还是使用花括号进行初始化都不会有什么影响。换句话说,现在看到<code>std::vector</code>设计的缺点以后你设计的时候避免它。</p>
|
||||
<p>这里的暗语是如果一个类没有<code>std::initializer_list</code>构造函数,然后你添加一个,用户代码中如果使用括号初始化,可能会发现过去被决议为非<code>std::initializer_list</code>构造函数而现在被决议为新的函数。当然,这种事情也可能发生在你添加一个函数到那堆重载函数的时候:过去被决议为旧的重载函数而现在调用了新的函数。<code>std::initializer_list</code>重载不会和其他重载函数比较,它直接盖过了其它重载函数,其它重载函数几乎不会被考虑。所以如果你要加入<code>std::initializer_list</code>构造函数,请三思而后行。</p>
|
||||
<p>第二个,作为一个类库使用者,你必须认真的在花括号和小括号之间选择一个来创建对象。大多数开发者都使用其中一种作为默认情况,只有当他们不能使用这种的时候才会考虑另一种。如果使用默认使用花括号初始化,会得到大范围适用面的好处,它禁止变窄转换,免疫C++最令人头疼的解析。他们知道在一些情况下(比如给一个容器大小和一个值创建<code>std::vector</code>)要使用小括号。如果默认使用小括号初始化,它们能和C++98语法保持一致,它避开了<code>auto</code>自动推导<code>std::initializer_list</code>的问题,也不会不经意间就调用了<code>std::initializer_list</code>构造函数。他们承认有时候只能使用花括号(比如创建一个包含着特定值的容器)。关于花括号和小括号的使用没有一个一致的观点,所以我的建议是用一个,并坚持使用。</p>
|
||||
<p>如果你是一个模板的作者,花括号和小括号创建对象就更麻烦了。通常不能知晓哪个会被使用。举个例子,假如你想创建一个接受任意数量的参数,然后用它们创建一个对象。使用可变参数模板(<em>variadic template</em>)可以非常简单的解决:</p>
|
||||
<p>第二个,作为一个类库使用者,你必须认真的在花括号和小括号之间选择一个来创建对象。大多数开发者都使用其中一种作为默认情况,只有当他们不能使用这种的时候才会考虑另一种。如果使用默认使用花括号初始化,会得到大范围适用面的好处,它禁止变窄转换,免疫C++最令人头疼的解析。他们知道在一些情况下(比如给一个容器大小和一个值创建<code>std::vector</code>)要使用小括号。如果默认使用小括号初始化,它们能和C++98语法保持一致,它避开了自动推导<code>std::initializer_list</code>的问题,也不会不经意间就调用了<code>std::initializer_list</code>构造函数。他们承认有时候只能使用花括号(比如创建一个包含着特定值的容器)。关于花括号和小括号的使用没有一个一致的观点,所以我的建议是选择一个方法并遵守它。</p>
|
||||
<p>如果你是一个模板的作者,花括号和小括号创建对象就更麻烦了。通常不能知晓哪个会被使用。举个例子,假如你想创建一个接受任意数量的参数来创建的对象。使用可变参数模板(<em>variadic template</em>)可以非常简单的解决:</p>
|
||||
<pre><code class="language-cpp">template<typename T, //要创建的对象类型
|
||||
typename... Ts> //要使用的实参的类型
|
||||
void doSomeWork(Ts&&... params)
|
||||
|
@ -1235,8 +1235,8 @@ std::vector<int> v2{10, 20}; //使用std::initializer_list构造函数
|
||||
</code></pre>
|
||||
<p>让我们退回之前的讨论。从这个讨论中我有两个重要结论。第一,作为一个类库作者,你需要意识到如果你的一堆重载的构造函数中有一个或者多个含有<code>std::initializer_list</code>形参,用户代码如果使用了括号初始化,可能只会看到你<code>std::initializer_list</code>版本的重载的构造函数。因此,你最好把你的构造函数设计为不管用户是小括号还是使用花括号进行初始化都不会有什么影响。换句话说,现在看到<code>std::vector</code>设计的缺点以后你设计的时候避免它。</p>
|
||||
<p>这里的暗语是如果一个类没有<code>std::initializer_list</code>构造函数,然后你添加一个,用户代码中如果使用括号初始化,可能会发现过去被决议为非<code>std::initializer_list</code>构造函数而现在被决议为新的函数。当然,这种事情也可能发生在你添加一个函数到那堆重载函数的时候:过去被决议为旧的重载函数而现在调用了新的函数。<code>std::initializer_list</code>重载不会和其他重载函数比较,它直接盖过了其它重载函数,其它重载函数几乎不会被考虑。所以如果你要加入<code>std::initializer_list</code>构造函数,请三思而后行。</p>
|
||||
<p>第二个,作为一个类库使用者,你必须认真的在花括号和小括号之间选择一个来创建对象。大多数开发者都使用其中一种作为默认情况,只有当他们不能使用这种的时候才会考虑另一种。如果使用默认使用花括号初始化,会得到大范围适用面的好处,它禁止变窄转换,免疫C++最令人头疼的解析。他们知道在一些情况下(比如给一个容器大小和一个值创建<code>std::vector</code>)要使用小括号。如果默认使用小括号初始化,它们能和C++98语法保持一致,它避开了<code>auto</code>自动推导<code>std::initializer_list</code>的问题,也不会不经意间就调用了<code>std::initializer_list</code>构造函数。他们承认有时候只能使用花括号(比如创建一个包含着特定值的容器)。关于花括号和小括号的使用没有一个一致的观点,所以我的建议是用一个,并坚持使用。</p>
|
||||
<p>如果你是一个模板的作者,花括号和小括号创建对象就更麻烦了。通常不能知晓哪个会被使用。举个例子,假如你想创建一个接受任意数量的参数,然后用它们创建一个对象。使用可变参数模板(<em>variadic template</em>)可以非常简单的解决:</p>
|
||||
<p>第二个,作为一个类库使用者,你必须认真的在花括号和小括号之间选择一个来创建对象。大多数开发者都使用其中一种作为默认情况,只有当他们不能使用这种的时候才会考虑另一种。如果使用默认使用花括号初始化,会得到大范围适用面的好处,它禁止变窄转换,免疫C++最令人头疼的解析。他们知道在一些情况下(比如给一个容器大小和一个值创建<code>std::vector</code>)要使用小括号。如果默认使用小括号初始化,它们能和C++98语法保持一致,它避开了自动推导<code>std::initializer_list</code>的问题,也不会不经意间就调用了<code>std::initializer_list</code>构造函数。他们承认有时候只能使用花括号(比如创建一个包含着特定值的容器)。关于花括号和小括号的使用没有一个一致的观点,所以我的建议是选择一个方法并遵守它。</p>
|
||||
<p>如果你是一个模板的作者,花括号和小括号创建对象就更麻烦了。通常不能知晓哪个会被使用。举个例子,假如你想创建一个接受任意数量的参数来创建的对象。使用可变参数模板(<em>variadic template</em>)可以非常简单的解决:</p>
|
||||
<pre><code class="language-cpp">template<typename T, //要创建的对象类型
|
||||
typename... Ts> //要使用的实参的类型
|
||||
void doSomeWork(Ts&&... params)
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user