最令人烦恼的解析

最令人烦恼的解析 （most vexing parse）是C++编程语言中的一种反直觉的二义性解析形式。 在一些场景下，编译器无法区分某语句是初始化时某对象的参数，还是声明一个函数时指定参数类型。在这些情况下，编译器将该行解释为函数声明。

 出现 
术语"most vexing parse" 最初由Scott Meyers用于2001年的书籍 Effective STL中。  尽管在C语言中不常见，但这种现象在 C++ 中很常见，直到C++11推出了统一初始化才得以解决。
 示例

 C风格强制类型转换 
一个例子如下：

void f(double my_dbl) {
  int i(int(my_dbl));
}

上面的第 2 行是有歧义的。一种可能的解释是声明一个变量 i ，初始值通过转换my_dbl 到一个int而来。但是，C 允许在函数参数声明周围使用多余的括号；因此，声明的i实际上等同于以下代码：

// A function named i takes an integer and returns an integer.
int i(int my_dbl);

 未命名的临时对象 
一个更可能出现的例子是：
struct Timer {};

struct TimeKeeper {
  explicit TimeKeeper(Timer t);
  int get_time();
};

int main() {
  TimeKeeper time_keeper(Timer());
  return time_keeper.get_time();
}

其中
  TimeKeeper time_keeper(Timer());

是有歧义的，它可以被解释为：
 一个变量：定义为类的变量，用类的匿名实例初始化。
 一个函数声明：声明了一个函数，返回一个，有一个（未命名的）参数。参数的类型是一个（指向）不接受输入并返回对象的函数（的指针）根据C++类型退化规则，作为参数声明的函数等价于一个指向同类型函数的指针。参见C++函数对象的实例。 。

C ++标准采取第二种解释，这与上面的第9行不一致。例如，Clang++警告第9行存在最令人烦恼的解析，并报错：
 $ clang++ time_keeper.cc
 timekeeper.cc:9:25:  parentheses were disambiguated as a function declaration
       [-Wvexing-parse]
   TimeKeeper time_keeper(Timer());

 timekeeper.cc:9:26: note: add a pair of parentheses to declare a variable
   TimeKeeper time_keeper(Timer());


 timekeeper.cc:10:21:  member reference base type 'TimeKeeper (Timer (*)())' is not a
       structure or union
   return time_keeper.get_time();


 解决方案 
这些有歧义的声明往往不会被解析为程序员所期望的语句。  C++ 中的函数类型通常隐藏在typedef之后，并且通常具有显式引用或指针限定符。要强制扭转解析的结果，常见做法是换一种不同的对象创建或转换语法。

在类型转换的示例中，有两种替代语法：“C 风格强制类型转换”

// declares a variable of type int
int i((int)my_dbl);或一个static_cast转换：

int i(static_cast<int>(my_dbl));在变量声明的示例中，首选方法（自 C++11 起）是统一（大括号）初始化。  这也允许完全省略类型名称：//Any of the following work:
TimeKeeper time_keeper(Timer{});
TimeKeeper time_keeper{Timer()};
TimeKeeper time_keeper{Timer{}};
TimeKeeper time_keeper(     {});
TimeKeeper time_keeper{     {}};在 C++11 之前，强制获得预期解释的常用手段是使用额外的括号或拷贝初始化：TimeKeeper time_keeper( /*Avoid MVP*/ (Timer()) );
TimeKeeper time_keeper = TimeKeeper(Timer());后一种写法中，拷贝赋值运算符 有可能被编译器优化。  自C++17开始，这种优化受到保证。  Note, however, the caveats covered in 

 注记 

参考资料

外部链接
 Discussion in the C++03 standard final draft (see §8.2 Ambiguity resolution [dcl.ambig.res]): https://web.archive.org/web/20141113085328/https://cs.nyu.edu/courses/fall11/CSCI-GA.2110-003/documents/c++2003std.pdf
CppReference on direct initialization (the sort vulnerable to the most vexing parse): https://en.cppreference.com/w/cpp/language/direct_initialization  

Category:C++
Category:带有C++代码示例的条目