默认构造函数/赋值操作符是否默认为noexcept和constexpr?

21

那么,我的问题很简单:

指定一个默认的类构造函数为 noexcept 或者 constexpr(或者其他你能想到的任何东西),有意义吗?

struct foo
{
   foo() = default;
   // vs
   constexpr foo() noexcept = default;

   // same thing would apply for copy/move ctors and assignment operators
};

这两种方式的行为会相同吗?

这是否取决于类是否为POD?例如,对于上面的示例,两者的行为都相同,而如果我有一个私有成员std :: vector<int> v = {1, 2, 3, 4}; 使用内部赋值,在编写foo()= default;时,默认情况下不会是noexceptconstexpr

编写foo()= default;是否会使编译器自动选择最佳版本:如果可能,则选择noexcept,如果可能,则选择constexpr等?

1个回答

26

[dcl.fct.def.default]/2-3:

2 如果显式默认的函数没有被定义为删除,则只有在它可以隐含声明为constexpr时,才能将其声明为constexpr。如果一个函数在第一次声明时显式地默认化,则:

  • 如果它的隐式声明将是constexpr,则它被隐含地认为是constexpr
  • 它具有与隐式声明相同的异常规范([except.spec])。

3 如果显式默认的函数的异常规范与隐式声明的异常规范不兼容([except.spec]),则:

  • 如果该函数在第一次声明时被显式默认化,则它被定义为已删除。

  • 否则,程序是非法的。

换句话说,foo() = default;,这个语句必须是foo默认构造函数的第一次声明,将会是“constexprnoexcept,如果可能的话"。显式地写constexprnoexcept仍然是有用的,它的含义是“如果不能 constexpr / noexcept ,则报错”。


2
认为向大家解释一下语法是有帮助的,即foo() noexcept = default,如 https://en.cppreference.com/w/cpp/language/noexcept_spec 所示。 - Louis Semprini
Visual Studio会为编译器提供的特殊成员函数以及用户提供的析构函数和释放器添加noexcept(true)规范,除非包含的成员或基类具有noexcept(false)的析构函数。请参见https://learn.microsoft.com/en-us/cpp/build/reference/zc-implicitnoexcept-implicit-exception-specifiers。不确定编译器提供的赋值运算符。 - MikeOnline

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接