【问题标题】:vexing parse in STL scott meyersSTL scott meyers 中令人烦恼的解析
【发布时间】:2018-05-14 05:11:32
【问题描述】:

我正在讨论第 6 条,它是关于 Effective STL: 50 Specific Ways to Improvement Your Use of the Standard Template Library 中最令人烦恼的解析,作者 Scott Meyers。

ifstream dataFile("ints.dat");
list<int> data(istream_iterator<int>(dataFile), // warning! this doesn't do
               istream_iterator<int>()); // what you think it does

所有这些都很有趣(以它自己扭曲的方式),但这并不能帮助我们说出我们想说的话,即应该使用文件的内容来初始化列表对象。现在我们知道我们必须击败什么解析,这很容易表达。用括号括住形参声明是不合法的,但是用括号括住函数调用的参数是合法的,因此通过添加一对括号,我们强制编译器以我们的方式看待事物:

list<int> data((istream_iterator<int>(dataFile)), // note new parens
                istream_iterator<int>0); // around first argument
                                         // to list's constructor

我的问题是作者所说的以下陈述是什么意思? “用括号括住形参声明是不合法的,但用括号括住函数调用的参数是合法的”

谢谢

【问题讨论】:

  • 那本书有些陈旧。现在你会使用统一初始化来破坏这种解析。
  • 你不能做int foo((int a))。但你可以做int foo((((42))));

标签: c++ stl most-vexing-parse


【解决方案1】:

作者下面的陈述是什么意思? 用括号括住形参声明是不合法的,但用括号括住函数调用的参数是合法的

Scott Meyers 的意思是,通过用括号将函数调用的参数括起来,它只能是一个函数调用,而不是一个函数声明,因为后者是非法的(即:排除了作为函数声明的可能性)。

否则,如果两者都是合法的,它将被解释为函数声明。这是因为 C++最令人头疼的解析:任何可以解释为声明的东西都会被解释为声明。


正如StoryTellerthis comment 中已经建议的那样,从C++11 开始,您可以使用大括号初始化

ifstream dataFile("ints.dat");
list<int> data{istream_iterator<int>(dataFile), istream_iterator<int>()}; 

上面的data 不会被解释为函数声明,因为函数声明中不允许使用大括号。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-20
    相关资源
    最近更新 更多