2017-08-25 9 views
3

有効なC++ 11は有効ですか?コンストラクタNoWay::NoWayの両方の引数にはデフォルト値がありますが、一方は宣言で指定され、他方は定義で指定されます。C++は、宣言と定義の間でデフォルトのパラメータ値を分割します

#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 

コンパイルが、打ち鳴らすが、問題は問題の核心1344として知られている

$ 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 
+0

ハードコーディングだけではなく、this-> foo = 4ですか? –

+1

必要なパラメータの前にオプションのパラメータを指定することはできません。引数リストの最後にのみパラメータを省略できるからです。 – Barmar

+0

@Barmar両方のパラメータはオプションであるが、宣言と定義の間では「オプションの構文的表現」を分割することが意図されています。あなたはその定義が構文的にうまく構成されていないと言っていますか? –

答えて

2

それを拒否:デフォルト経由クラスに新しい特別なメンバ関数を追加します引数

c++14 standardによると、構文的に正当な主体であれば、新しいデフォルトは既に定義済みのものに追加されます。

8.3.6.6クラステンプレートのメンバ関数を除いて、クラス定義の外部に表示されるメンバ関数定義のデフォルト引数は、クラス定義のメンバ関数宣言によって提供されるデフォルト引数のセットに追加されます;

しかし、病気のデフォルトコンストラクタ(12.1)場合

8.3.6.6プログラムが悪い形成されている場合、コンストラクタをコピーまたは移動、形成、または代入演算子(12.8)をコピーまたは移動がそう宣言されています。

だから、clangが正しいです。少なくともC++では14

1

エラーを報告するには正しいです。 N4659を引用し、[dcl.fct.default]、段落6:クラステンプレートのメンバ関数を除き

、クラス定義の外 が表示されますがセットに追加されていることをメンバー関数定義のデフォルト引数メンバーによって提供されるデフォルトの引数 クラス定義内の関数宣言。デフォルトコンストラクタ(15.1)、コピー またはコンストラクタの移動、または代入演算子(15.8)のコピーまたは移動が宣言されている場合、プログラムは不正です。それ

は、限り、あなたはすでにデフォルトを持っているパラメータの値を指定しないと、(非テンプレート)関数が定義された(または再宣言)され、他のパラメータのデフォルト値を宣言する有効です翻訳単位間でODRが違反していないかぎりです。

関連する問題