これは私の以前の質問に対するフォローアップです: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::string
でa
という名前作成します。 a char*
。 (マイ所望の解釈)
又は
(2)std::string*
かかりa
という名前の関数の宣言(ない定義を)。
元の質問への回答から、関数は別の関数の範囲内で宣言できることを知りました。それは私には新しかったが、理由のように思われる、私はそれを買うことができる。
私は頭を包むことはできませんが、std::string(argv[1])
の解釈はstd::string*
です。
argv [1]はchar *なので、なぜこの行が匿名として解釈されないのかわかりません。std::string
はchar*
で構成されています。私はのカスプによ
#include <iostream>
int main()
{
char* pFoo[] = {"foo"};
std::string str(pFoo[0]);
std::cout << str << std::endl;
return 0;
}
:すべての後、私は今まで、これはそのchar*
コンストラクタとstd::string
の建設以外の何かにつながるかどうかを精査することなく、時間の次数百に類似したコードを使用しました最も厄介な解析問題を理解する。もし誰かがこの最後のいたずらを説明することができれば、それは私を端に押しやるのを助けるかもしれない。
ありがとうございます。
これは私が最も厄介な解析については得られないものです。 'std :: string(argv [1])'は 'std :: string argv [1]'と同じですか?この場合、中括弧はまったく変わりませんか? 'int f(float arg)'関数を考えてみましょう: 'int f(float(arg))'は同等ですが、そうではないようです。 –
はい、意味を変えずに任意の宣言子のまわりにかっこを追加できます。 – aschepler
あなたは正しくなければなりません、GCCは 'int f(float(arg))'に対して、私が期待していたのとは逆のエラーを投げません。 –