2016-08-19 3 views
3

これは私の以前の質問に対するフォローアップです:C++ compile error constructing object with rvalue std::stringこれから、私はMost Vexing Parseについて学びました。ほとんどのVexingのインスタンスは、std :: stringとchar *を使って解析します。

私は今問題の要点を理解していますが、構文の残りの部分があります。これはまだ分かりません。前回の記事の議論がかなり進んでいたので、スタンドアロンの質問として聞きたいのですが長いです。このコードを考えると

#include <iostream> 
#include <string> 

class Foo 
{ 
    public: 
     Foo(double d) 
      : mD(d) 
     { 
     } 

     Foo(const std::string& str) 
     { 
      try 
      { 
       mD = std::stod(str); 
      } 
      catch (...) 
      { 
       throw; 
      } 
     } 

     Foo(const Foo& other) 
      : mD(other.mD) 
     { 
     } 

     virtual ~Foo() {} 

    protected: 
     double mD; 
}; 

class Bar 
{ 
    public: 
     Bar(const Foo& a, const Foo& b) 
      : mA(a) 
      , mB(b) 
     { 
     } 

     virtual ~Bar() {} 

    protected: 
     Foo mA; 
     Foo mB; 
}; 

int main(int argc, char* argv[]) 
{ 
    if (argc < 3) { return 0; } 

    Foo a(std::string(argv[1])); 
    Foo b(std::string(argv[2])); 

    Bar wtf(a, b); 
} 

私はラインFoo a(std::string(argv[1]));があると解釈することができることを、今、理解し、次のいずれか

(1)はFooを使用して作成された匿名std::stringaという名前作成します。 a char*。 (マイ所望の解釈)

又は

(2)std::string*かかりaという名前の関数の宣言(ない定義を)。

元の質問への回答から、関数は別の関数の範囲内で宣言できることを知りました。それは私には新しかったが、理由のように思われる、私はそれを買うことができる。

私は頭を包むことはできませんが、std::string(argv[1])の解釈はstd::string*です。

argv [1]はchar *なので、なぜこの行が匿名として解釈されないのかわかりません。std::stringchar*で構成されています。私はのカスプによ

#include <iostream> 
int main() 
{ 
    char* pFoo[] = {"foo"}; 
    std::string str(pFoo[0]); 
    std::cout << str << std::endl; 
    return 0; 
} 

:すべての後、私は今まで、これはそのchar*コンストラクタとstd::stringの建設以外の何かにつながるかどうかを精査することなく、時間の次数百に類似したコードを使用しました最も厄介な解析問題を理解する。もし誰かがこの最後のいたずらを説明することができれば、それは私を端に押しやるのを助けるかもしれない。

ありがとうございます。

答えて

4
Foo a(std::string(argv[1])); 

Fooを戻し、タイプstd::string[1]の(argv命名)つのパラメータを有するaという名前の関数を宣言します。配列関数のパラメーターは常にポインターパラメーターに置き換えられるため、関数パラメーターの実際の型はstd::string*になります。

+0

これは私が最も厄介な解析については得られないものです。 'std :: string(argv [1])'は 'std :: string argv [1]'と同じですか?この場合、中括弧はまったく変わりませんか? 'int f(float arg)'関数を考えてみましょう: 'int f(float(arg))'は同等ですが、そうではないようです。 –

+0

はい、意味を変えずに任意の宣言子のまわりにかっこを追加できます。 – aschepler

+0

あなたは正しくなければなりません、GCCは 'int f(float(arg))'に対して、私が期待していたのとは逆のエラーを投げません。 –

関連する問題