2

私はこのクラスを持っています。委譲コンストラクターを使用して、値のみを0としてX変更したいのですが、それは可能ですか?ij

class X{
public:
    X() = default; 
    X(int ival, int jval) : i{ ival }, j{ jval } {} 
    X(int new_i) : i{ new_i }, X(i, 0) {}    //error here


private:
    int i; 
    int j; 
};

int main()
{
    X x{ 345, 54 };

    x = X{ 34 };  //annoymous copy changes only the i:member
    return 0; 
}

編集:私X(int new_int) : X{new_int, 0}は動作することを知っていますが、リスト内のもう 1 つの変数を初期化した場合のエラーを知りたいと思いました。

私は別のものを持っている可能性があり、それをとzとともに初期化したいと思います。ij

すなわちX(int new_i) :z{ new_i }, X(new_i, 0) {}

4

3 に答える 3

2

使うだけ

X(int new_i) :  X(new_i, 0) {}

C++ Draft Standard N3337 (強調鉱山) から:

12.6.2 ベースとメンバーの初期化

6 Aは、コンストラクターのクラス自体を示すmem-initializer-listany を使用して、コンストラクターのクラスの別のコンストラクターに委譲できます。aがコンストラクターのクラスを指定する場合、それは唯一のものでなければなりませんclass-or-decltypemem-initializer-idmem-initializer

于 2015-02-27T19:23:10.590 に答える
1

初期化子リストに委譲コンストラクター別のメンバー初期化子を含めることはできません。初期化の順序がメンバー宣言の順序である可能性はあり得ないため、これは許可されていません。代わりに、一部の変数が 2 回初期化され、不適切に定義されている可能性があります。

あなたの例が許可されている場合、問題のコンストラクターは最初に <- を初期化しinew_i次にi<-- i、次にj< -- を初期化します0。non-const intの場合、これは実現可能かもしれませんが、より一般的な型ではそうではありません。


委任を介してオブジェクトを初期化するだけです。

class X
{
public:
  X() = default; 
  X(int ival, int jval) : i{ival}, j{jval} {} 
  X(int ival) : X(ival, 0) {}    
private:
  int i; 
  int j; 
};

ただし、この場合、デフォルトの引数を使用することをお勧めします。

class X
{
public:
  X() = default; 
  X(int ival, int jval=0) : i{ival}, j{jval} {} 
private:
  int i; 
  int j; 
};

explicit不愉快な驚きを避けるために、単一引数のコンストラクターにキーワードを使用することも検討する必要があります...のように

void foo(X);
foo(1);       // calls foo(X(1));
于 2015-02-27T19:23:08.660 に答える
1

なぜあなたはこれをしないのですか?

X(int new_i) :X(new_i, 0){...}

このように、j-th の値を 0 に設定し、x変数のみを使用します。

于 2015-02-27T19:20:45.527 に答える