C ++,构造函数中允许的引用参数默认值

时间:2017-11-24 13:16:06

标签: c++ c++11

在.h文件中

class X{
private:
  std::chrono::minutes A;
public:
  X(std::chrono::minutes& a = std::chrono::minutes {5});
}

在.CPP文件中

X::X(std::chrono::minutes& a): A(a){}

在分配给A

之前,std :: chrono :: minutes {5}可以超出范围

例如,

void main()
{
   X x;
}

是否保证对象x的成员A的值始终为std :: chrono :: minutes {5}?

1 个答案:

答案 0 :(得分:3)

让我们看一下代码的简化版本:

#include <chrono>

struct X{
  std::chrono::minutes A;
  X(std::chrono::minutes const& a = std::chrono::minutes {5}) 
    : A(a){}
};

void main()
{
   X x; //Construction.
}

我已将参考更改为const,以符合标准。

这段代码很好。临时是在main(在标记为“构造”的行)的上下文中创建的,并且引用参数绑定到它。调用构造函数,一旦参数超出范围,临时就会被销毁。

(当然,如果成员变量是引用而不是实际对象,那么你将有一个悬空引用。)

使用非const引用的编译器定义是违反约束 - 您不能将非const引用绑定到临时。可悲的是,默认情况下,MSVC不会抱怨这一点。在MSVC17之前,你唯一能做的就是:

  • 使用合适的命令行选项或pragma
  • 将警告C4239提升为错误
  • 使用/ w4运行。然而,在早期版本中,这基本上无法使用,因为STL充满了W4警告。第三方图书馆很可能仍然存在。
  • 使用/ Za运行(禁用扩展) - 这通常不会编译所需的标题。

最后在VC2017,他们引入了/permissive-(我强烈建议您作为默认设置)。