条款7 辨别使用()与{}创建对象的差别

基础知识

  目前已知有如下的初始化方式:

int x();
int y = ;
int z{};
int z = {}; // the same as above

  在以“=”初始化的过程中没有调用赋值运算,如下例所示:

Widget w1; // default ctor
Widget w2 = w1; // copy ctor
w1 = w2; // assignment, operator =

  还可以用来初始化:

class Widget {
int x{}; // fine
int y = ; // fine
int z(); // error
}; std::atomic<int> ai1{}; // fine
std::atomic<int> ai2(); // fine
std::atomic<int> ai3 = ; // error

  在构造函数中,()与{}在不含有的std::initializer_list的时候意义相同。但是如果出现std::initializer_list,则使用{}初始化语法的时候更倾向调用重载过后的函数。甚至那些拷贝和移动构造函数也会被劫持,例如:

class Widget {
public:
Widget(int i, bool b);
Widget(int i, double d);
Widget(std::initializer_list<long double> il);
operator float() const;
}; Widget w5(w4); // copy ctor
Widget w6{w4}; // w4 -> float -> initializer_list<long double>

  std::initializer_list构造函数太强烈, 以致最优的匹配函数不是它,也会因缩窄匹配而错误:

Widget(std::initializer_list<bool> il);

Widget w{, 5.0}; // error, narrowing conversions

  只有在不能通过转换匹配的情况下,编译器才查找原来的函数:

Widget(std::initializer_list<std::string> il);

Widget w{, 5.0}; // OK

  在空值的情况下:

Widget w1; // default ctor
Widget w2{}; // default ctor
Widget w3(); // most vexing parse! function

总结

  • {}初始化时最多使用的初始化语法,它不能进行缩窄转换(narrowing conversion),并且对一些令人烦恼的解析(most vexing parse)免疫
  • 在构造函数重载解析过程中,{}初始化优先匹配std::initializer_list,即使其他构造函数更匹配
  • 使用()或者{}的方式创建std::vector<numeric type>会有很大的不同
  • 在模板中选择()或{}方式创建对象是一个挑战

[Effective Modern C++] Item 7. Distinguish between () and {} when creating objects - 辨别使用()与{}创建对象的差别的更多相关文章

  1. [Effective Modern C++] Item 6. Use the explicitly typed initializer idiom when auto deduces undesired types - 当推断意外类型时使用显式的类型初始化语句

    条款6 当推断意外类型时使用显式的类型初始化语句 基础知识 当使用std::vector<bool>的时候,类型推断会出现问题: std::vector<bool> featu ...

  2. [Effective Modern C++] Item 5. Prefer auto to explicit type declarations - 相对显式类型声明,更倾向使用auto

    条款5 相对显式类型声明,更倾向使用auto 基础知识 auto能大大方便变量的定义,可以表示仅由编译器知道的类型. template<typename It> void dwim(It ...

  3. [Effective Modern C++] Item 4. Know how to view deduced types - 知道如何看待推断出的类型

    条款四 知道如何看待推断出的类型 基础知识 有三种方式可以知道类型推断的结果: IDE编辑器 编译器诊断 运行时输出 使用typeid()以及std::type_info::name可以获取变量的类型 ...

  4. [Effective Modern C++] Item 3. Understand decltype - 了解decltype

    条款三 了解decltype 基础知识 提供一个变量或者表达式,decltype会返回其类型,但是返回的内容会使人感到奇怪. 以下是一些简单的推断类型: ; // decltype(i) -> ...

  5. [Effective Modern C++] Item 2. Understand auto type deduction - 了解auto类型推断

    条款二 了解auto类型推断 基础知识 除了一处例外,auto的类型推断与template一样.存在一个直接的从template类型推断到auto类型推断的映射 三类情况下的推断如下所示: // ca ...

  6. [Effective Modern C++] Item 1. Understand template type deduction - 了解模板类型推断

    条款一 了解模板类型推断 基本情况 首先定义函数模板和函数调用的形式如下,在编译期间,编译器推断T和ParamType的类型,两者基本不相同,因为ParamType常常包含const.引用等修饰符 t ...

  7. Effective Modern C++ Item 27:重载universal references

    假设有一个接收universal references的模板函数foo,定义如下: template<typename T> void foo(T&& t) { cout ...

  8. Effective Modern C++ Item 37:确保std::thread在销毁时是unjoinable的

    下面这段代码,如果调用func,按照C++的标准,程序会被终止(std::terminate) void func() { std::thread t([] { std::chrono::micros ...

  9. Effective Modern C++ 42 Specific Ways to Improve Your Use of C++11 and C++14

    Item 1: Understand template type deduction. Item 2: Understand auto type deduction. Item 3: Understa ...

随机推荐

  1. iOS-tableView点击下拉菜单

    #import "ViewController.h" @interface ViewController ()<UITableViewDataSource,UITableVi ...

  2. C# List<T>的详细用法

    所属命名空间:System.Collections.Generic List<T>类是 ArrayList 类的泛型等效类.该类使用大小可按需动态增加的数组实现 IList<T> ...

  3. 第1个linux命令——echo

    功能:在显示器上显示一段文字,一般起到一个提示的作用. 语法:echo [-ne][字符串]    或   echo [--help][--version] 详细说明:echo会将输入的字符串送往标准 ...

  4. (转) c++ 迭代器

    原地址:http://www.cnblogs.com/marchtea/archive/2012/02/27/2370068.html 前言: 以下的内容为我阅读c++沉思录18,19,20章的笔记以 ...

  5. codeforces 337C Quiz(贪心)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Quiz Manao is taking part in a quiz. The ...

  6. C++语法报错收集

    1. error C2864: "OuterClass::m_outerInt": 只有静态常量整型数据成员才可以在类中初始化 class OuterClass { public: ...

  7. 为编写网络爬虫程序安装Python3.5

    1. 下载Python3.5.1安装包1.1 进入python官网,点击menu->downloads,网址:https://www.python.org/downloads/ 1.2 根据系统 ...

  8. wine下汉字方块解决

    1.修改字体 首先,下载一个字体,例如win下的新宋体 其次, mkdir /usr/share/fonts/windows mv simsun.ttc /usr/share/fonts/window ...

  9. C语言函数入门

    由于采用了函数模块式的结构,C语言易于实现结构化程序设计.使程序的层次结构清晰,便于程序的编写.阅读.调试. main 函数是主函数,它可以调用其它函数,而不允许被其它函数调用.因此,C程序的执行总是 ...

  10. ASP.NET MVC 4.0 学习1-C#基础语法

    1,方法多載,相同的方法名稱,不同的參數類型.數量 class Program { static void Main(string[] args) { Program newObject = new ...