C ++在声明和定义之间拆分默认参数值

时间:2017-08-25 23:59:24

标签: c++

以下是否有效的C ++ 11?构造函数NoWay::NoWay的两个参数都有默认值,但在声明中指定了一个,在定义中指定了另一个。

#include <iostream>

class NoWay {
private:
  int foo;
  bool bar;

public:
  explicit NoWay(int foo, bool bar = true);
  bool isGood();
};

NoWay::NoWay(int foo = 4, bool bar) {
  this->foo = foo;
  this->bar = bar;
}

bool NoWay::isGood() { return (foo == 4) && (bar == true); }

int main(int argc, char **argv) {
  auto noway = NoWay();
  std::cout << noway.isGood() << std::endl;
}

这在gcc

下编译没有错误
$ g++ --std=c++11 foo.cc

但是clang拒绝了它

$ clang++ --std=c++11  foo.cc
foo.cc:13:18: error: addition of default argument on redeclaration makes this constructor a default constructor
NoWay::NoWay(int foo = 4, bool bar) {
                 ^     ~
foo.cc:9:12: note: previous declaration is here
  explicit NoWay(int foo, bool bar = true);
           ^
1 error generated.
Exit 1

2 个答案:

答案 0 :(得分:2)

该问题被称为核心问题1344:通过默认参数将新的特殊成员函数添加到类

根据语法上有效的c++14 standard,新的默认值只是添加到已经定义的内容中。

  

8.3.6.6除了类模板的成员函数之外,出现在类定义之外的成员函数定义中的缺省参数被添加到类定义中成员函数声明提供的缺省参数集中;

但如果

生病了
  

8.3.6.6如果声明了默认构造函数(12.1),复制或移动构造函数或复制或移动赋值运算符(12.8),则程序格式错误。

所以铿锵是对的。至少在C ++ 14

答案 1 :(得分:1)

Clang报告错误是正确的。引用N4659,[dcl.fct.default],第6段:

  

除了类模板的成员函数之外,成员函数定义中的默认参数   出现在类定义之外的内容被添加到成员提供的默认参数集中   类定义中的函数声明;如果默认构造函数(15.1),则程序格式错误,复制   或移动构造函数,或复制或移动赋值运算符(15.8)如此声明。

有效,在定义(或重新声明)(非模板)函数时声明其他参数的默认值,只要您不指定参数的值即可已经有一个默认值,只要翻译单位没有违反ODR。