条款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. OER 7451 in Load Indicator : Error Code = OSD-04500:指定了非法选项

    alert 日志错误OER 7451 in Load Indicator : Error Code = OSD-04500:指定了非法选项 Sun Apr 22 11:15:51 2012 OER 7 ...

  2. JavaScript、Ajax与jQuery的关系

    简单总结: 1.JS是一门前端语言. 2.Ajax是一门技术,它提供了异步更新的机制,使用客户端与服务器间交换数据而非整个页面文档,实现页面的局部更新. 3.jQuery是一个框架,它对JS进行了封装 ...

  3. 【5】将服务部署到本机(Ubuntu14.04)

    首先,先将文件复制到指定的文件夹 我这里选择在/var下面新建一个www的文件夹来存放 复制BLOG文件夹的内容到www文件夹下 sudo cp -r /home/jakeychen/Jakey/Bl ...

  4. 【2】开发环境的搭建,Ubuntu14.04

    这里使用的是Ubuntu14.04 Unity 更新源 首先,将更新源更换为国内更新源,我这里使用的是网易的更新源 sudo gedit /etc/apt/sources.list deb http: ...

  5. winform 窗口点击窗体任意位置移动窗体

    private bool _isDown; private Point _mousePoint; private void Users_MouseDown(object sender, MouseEv ...

  6. 三星S5驱动安装

    三星S5的驱动安装一定要先用原装的数据线链接电脑,在电脑里面安装完驱动之后,以后才能每次都用正常的数据线链接 不然的话会提示某些驱动安装不正常..

  7. Ext4报错Uncaught Ext.Loader is not enabled

    提示: Uncaught Ext.Loader is not enabled, so dependencies cannot be resolved dynamically. Missing requ ...

  8. C和指针c6-1

    #include<stdio.h> #include<stdlib.h> char *find_char(char const *source_str, char const ...

  9. Windows7里的“计算器”你真的会用吗?

    “计算器”是不同Windows版本中的必备工具,虽然功能单一,但的确是人们日常工作中不可缺少的辅助工具,本文就来谈谈它的使用. 一.标准型和科学型两种面板 我们既可从Windows附件菜单中启动它,也 ...

  10. [置顶] SPL讲解(7)--Query高级篇

    SmartPersistenceLayer 2.0 之Query高级查询篇 总述 在看了前面的功能后,大家都会考虑到多表之间的查询怎么办.在这里,我想先讲一下查询在应用系统中的复杂性/重要性/可行性. ...