-1

C++11 では、コンストラクターを初期化リスト内の別のコンストラクターに転送できます。

この質問のように、初期化リストで関数を呼び出しても問題ありません

コンストラクターデリゲートで関数を呼び出しても問題ありませんか?

私はこのようなコードを試しました:

#include <iostream>
#include <string>
#include <yaml-cpp/yaml.h>

using namespace std;

YAML::Node ParseFromFile(const string& filepath) {
  YAML::Node yaml;
  try {
    return YAML::LoadFile(filepath);
  } catch(const YAML::BadFile& e) {
    cout << "error";
  }
}

class A {
 public:
  A(YAML::Node yaml) {
    cout  << "Got" << endl;
  }
  A(const string& filepath) : A(ParseFromFile(filepath)) {}
};


int main(int argc, char** argv) {
  A a(string(argv[1]));
  YAML::Node yaml = ParseFromFile(string(argv[1]));
  A b(yaml);
  return 0;
}

上記のコードでは、空のファイルを渡すだけで、b の初期化中に "Got" が 1 つだけ出力されます。

================================================== =====================

string(argv[1]) を argv[1] に置き換えると機能しますが、その理由は何ですか?

4

1 に答える 1

3

編集された質問への回答


問題は、変数の初期化としてではなく、関数宣言として扱われるメインの最初の行です。実際、これを clang でコンパイルすると、これに関する警告が表示されます。

警告: 括弧は関数宣言として明確化されました

これは、 § 6.8定義されているものによるものです。

式ステートメントと宣言を含む文法にはあいまいさがあります。左端の部分式として関数スタイルの明示的な型変換 (5.2.3) を使用する式ステートメントは、最初の宣言子が ( で始まる宣言と区別できない場合があります。そのような場合、ステートメントは宣言です。

次の例を検討してください。

#include <iostream>
#include <string>
#include <exception>
using namespace std;

struct A{
    string a;
    A(string s) : a(s){ cout<< "Ctor" <<endl;}
    A(int i) : A(to_string(i)){ }
};

void foo (A (*a)(string*)){
    cout<<"yay"<<endl;
}

int main(int argc, char** argv) {
    A         a1(     string(argv[1]) ); // function A a1(std::string*) declaration not a variable 
/*  ^         ^       ^
    |         |       |
return type   name   arg type 
Same as foo
*/
    // foo(a1);//  <- compiles but fails only due to linkage         
    A  a2 = A(string(argv[1])); // works
    A  a3{string(argv[1])}; // works
    A  a4(string{argv[1]}); // works
    A         a5(     ( string(argv[1]) ) ); // works allso but confusing imho
/*                    ^                 ^
notice extra paren.   |                 |
*/  
    return 0;
}

元の質問への回答 FWIW


試してみませんか?

まだ初期化されていないメンバーを使用する関数を呼び出さない限り、問題はないはずです。

例 (デモ):

#include <iostream>
#include <string>
using namespace std;

class A {
 public:
  A(string x) {
    cout  << "Got "  << x << endl;
  }
  A(int x) : A(std::to_string(x)) {}
};


int main() {
    A a(15);
    return 0;
}
于 2014-08-07T05:22:58.593 に答える