【问题标题】:Most vexing parse confusion最令人头疼的解析混淆
【发布时间】:2013-06-08 06:48:25
【问题描述】:

我正在学习 C++11,偶然发现了统一初始化程序。

我不明白以下代码应该显示“最令人烦恼的解析”歧义:

#include<iostream>


class Timer
{
public:
  Timer() {}
};

int main() 
{

  auto dv = Timer(); // What is Timer() ? And what type is dv?

  int time_keeper(Timer()); // This is a function right? And why isn't the argument " Timer (*) ()" ?



  return 0;
}

【问题讨论】:

  • AFAIK 第二行调用 MVP,第一行没有。
  • 我知道,但我对代码中涉及的类型感到困惑

标签: c++ class c++11 function-pointers


【解决方案1】:

这里:

auto dv = Timer();

您有一个名为 dvTimer 类型的对象,它正在从一个临时对象(= 符号右侧的表达式)进行复制初始化。

当使用auto 声明一个变量时,该变量的类型与初始化它的表达式的类型相同——这里不考虑 cv 限定符和引用。

在您的情况下,初始化dv 的表达式具有Timer 类型,因此dv 具有Timer 类型。

这里:

int time_keeper(Timer());

您声明了一个名为 time_keeper 的函数,该函数返回一个 int,并将一个指针作为其输入,该指针指向一个返回 Timer 且不带任何参数的函数。

为什么不是Timer (*) () 的论点?

函数在作为参数传递时衰减为指针,因此time_keeper 的类型实际上是int(Timer(*)())

为了说服自己,你可以尝试编译这个小程序:

#include <type_traits>

struct Timer { };
int main()
{
    int time_keeper(Timer());
    static_assert(
        std::is_same<
            decltype(time_keeper), 
            int(Timer(*)())
        >::value, 
        "This should not fire!");
}

这是live example

【讨论】:

  • 谢谢,参数不应该是 "Timer (*) ()" 吗? “Timer()”也是可接受的函数指针吗?
  • 我猜,functionName&amp;functionName 是同一件事。
  • @DavidKernin:函数在用作函数参数时会自动衰减为指针,因此void(Timer())void(Timer(*)()) 是相同的类型。
  • 老实说,断言是用 MSVC2012 抛出的,但我认为这是一个与编译器相关的错误。
  • @DavidKernin:我相信是的。对于 SO 来说,这听起来像是一个有趣的新问题 :)
猜你喜欢
  • 2020-08-17
  • 1970-01-01
  • 2018-05-26
  • 2019-11-30
  • 2013-08-02
  • 1970-01-01
  • 2018-07-21
  • 1970-01-01
相关资源
最近更新 更多