C++'s most vexing parse 是 Scott Meyers 在其名著《Effective STL》中创造的一个术语。

Scott 用这个术语来形容 C++ 标准对于 declaration 语句的消歧义(ambiguity resolution)约定与常人的认知相悖。

形如 Type()Type(name) 的表达在某些情况下具有歧义(syntax ambiguity)。

T1 name(T2());

这是一个 declaration statement。

既可视作声明了一个类型为 T1 名为 name 的 object,并且用一个类型为 T2 的 object 作为其 initilizer(即标准中所谓「an object declaration with a function-style cast as the initializer」),也可视作声明了一个返回值类型为 T1 名为 name 的函数,此函数有一个参数,参数类型为「指向返回值类型为 T2,参数为空的函数的指针」。

C++ 标准规定把这样的 statement 视作函数声明。

T1 name1(T2(name2));

根据 C++ 标准,此时不把 T2(name2) 视为「a function style cast」,而将其视为 T2 name2,这样整个语句就变成

T1 name1(T2 name2);,显然这是个函数声明。

类似地,

T1 name1(T2(name2), T3(name3)); 被视作 T1 name1(T2 name2, T3 name3);

C++ 标准将上述两种情况总结为

..., the choice is between a function declaration with a redundant set of parentheses around a parameter name and an object declaration with a function-style cast as the initializer. ..., the resolution is to consider any construct that could possibly be a declaration a declaration... A declaration can be explicitly disambiguated by adding parentheses around the argument. The ambiguity can be avoided by use of copy-initialization or list-initialization syntax, or by use of a non-function-style cast.

并给出了例子

struct S {
S(int);
}; void foo(double a) {
S w(int(a)); // function declaration
S x(int()); // function declaration
S y((int(a))); // object declaration
S y((int)a); // object declaration
S z = int(a); // object declaration
}

不难看出,the most vexing parse 的根源在于default constructor、converting constructor 和 conversion operator。

converting constructor 是指调用时只需一个实参的 constructor。From C++ Primer (5th edition):

Every constructor that can be called with a single argument defines an implicit conversion to a class type. Such constructors are sometimes referred to as converting constructors.

C++ Primer 上关于 conversion operator 的内容

A conversion operator is a special kind of member function that converts a value of a class type to a value of some other type. A conversion function typically has the general form

operator T() const;

where T represents a type.

Conversion operators have no explicitly stated return type and no parameters, and they must be defined as member functions. Conversion operations ordinarily should not change the object they are converting. As a result, conversion operators usually should be defined as const members.

More to read

The Most Vexing Parse: How to Spot It and Fix It Quickly

【C++ 拾遗】C++'s most vexing parse的更多相关文章

  1. Effective STL 笔记: Item 6--Be alert for C++'s most vexing parse

    假设有个文件里面记录的一系列的 int 值,现在我们想把这些数值存到一个 List 里面,结合 Item 5, 我们可能会写出下面的代码: ifstream dataFile("ints.d ...

  2. C++ 11 多线程--线程管理

    说到多线程编程,那么就不得不提并行和并发,多线程是实现并发(并行)的一种手段.并行是指两个或多个独立的操作同时进行.注意这里是同时进行,区别于并发,在一个时间段内执行多个操作.在单核时代,多个线程是并 ...

  3. (转)C++语言的15个晦涩特性

    原文链接: Evan Wallace   翻译: 伯乐在线- 敏敏 译文链接: http://blog.jobbole.com/54140/ 这个列表收集了 C++ 语言的一些晦涩(Obscure)特 ...

  4. C++你不知道的那些事儿—C++语言的15个晦涩特性

    这个列表收集了 C++ 语言的一些晦涩(Obscure)特性,是我经年累月研究这门语言的各个方面收集起来的.C++非常庞大,我总是能学到一些新知识.即使你对C++已了如指掌,也希望你能从列表中学到一些 ...

  5. [译]GotW #1: Variable Initialization 续

    Answer 2. 下面每行代码都做了什么? 在Q2中,我们创建了一个vector<int>且传了参数10和20到构造函数中,第一种情况下(10,20),第二种情况是{10, 20}. 它 ...

  6. [译]GotW #1: Variable Initialization

    原文地址:http://herbsutter.com/2013/05/09/gotw-1-solution/ 第一个问题强调的是要明白自己在写什么的重要性.下面有几行简单的代码--它们大多数之间都有区 ...

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

    条款7 辨别使用()与{}创建对象的差别 基础知识 目前已知有如下的初始化方式: ); ; }; }; // the same as above 在以“=”初始化的过程中没有调用赋值运算,如下例所示: ...

  8. c++ 多线程 0

    1.1 何谓并发 最简单和最基本的并发,是指两个或更多独立的活动同时发生.  (注意区别于计算机中的并发情况!!!!!!!!!!见下面) 1.1.1 计算机系统中的并发:是指在单个系统里同时执行多个独 ...

  9. C++学习书籍推荐《Effective STL(英文)》下载

    百度云及其他网盘下载地址:点我 作者简介 Scott Meyers is one of the world's foremost authorities on C++, providing train ...

随机推荐

  1. PowerDesigner生成sql脚本

    1.打开PowerDesigner->New Project; 2.填写项目名称,选择文件的存放路径: 3.新建一个模型,New Model: 4.选择概念模型,填写模型名称: 5.选择enti ...

  2. Hutool Wiki For java

    发现一款不错的java工具类, http://www.hutool.cn/ Hutool的使用文档. 项目见 https://github.com/looly/hutool 以及 http://git ...

  3. Linux系统崩溃,数据迁移

    就在1小时前,处理了件如标题所述的麻烦事儿.吃完午饭,想对此作个总结,一来自己梳理下过程以便后面遇见类似的事可以 快速处理,二来同行的小伙伴们可以探讨下.故事是这样的,公司所在园区物业晚上断电8小时, ...

  4. Java高并发之线程基本操作

    结合上一篇同步异步,这篇理解线程操作. 1.新建线程.不止thread和runnable,Callable和Future了解一下 package com.thread; import java.tex ...

  5. cx_freeze的安装使用

    python是一个非常非常优秀的编程语言,它最大的特性就是跨平台.python程序几乎可以在所有常见的平台中进行使用,而且大部分无需修改任何代码!不过,python也有一点点小缺憾(这个是由于自身本质 ...

  6. Oracle_11g中解决被锁定的scott用户的方法

    在安装完Oracle10g和创建完oracle数据库之后,想用数据库自带的用户scott登录,看看连接是否成功. 问题: 在cmd命令中,用“sqlplus  scott/ tiger”登录时,老是提 ...

  7. lan口和wan口的配置

    路由器的一排网线接口,分为 lan 和 wan .但不是谁生来就是lan口 或者 wan口 . 也没有谁规定就一个wan口 就只有一个. 网口就是网口, 决定它是 lan口 还是 wan口 ,是由我们 ...

  8. [Bzoj1037][ZJOI2008]生日聚会(DP)

    Description 题目链接 Solution 这题状态比较难想, \(dp[i][j][g][h]\)表示强i个人有j个男生,在某个区间男生最多比女生多g人,女生最多比男生多h人的方案数,然后D ...

  9. poj 3111 卖珠宝问题 最大化平均值

    题意:有N件分别价值v重量w的珠宝,希望保留k件使得 s=v的和/w的和最大 思路:找到贡献最大的 设当前的s为mid(x) 那么贡献就是 v-w*x 排序 ,取前k个 bool operator&l ...

  10. WPF制作的小时钟

    原文:WPF制作的小时钟 周末无事, 看到WEB QQ上的小时钟挺可爱的, 于是寻思着用WPF模仿着做一个. 先看下WEB QQ的图: 打开VS, 开始动工. 建立好项目后, 面对一个空荡荡的页面, ...