7

Observation: the codes pasted below were tested only with GCC 4.4.1, and I'm only interested in them working with GCC.

こんにちは、

理解できないオブジェクト構築ステートメントに出くわしたのはほんの数回ではありませんでした。そして、それによってどのような曖昧さがもたらされているかに気付いたのは今日だけでした。それを再現する方法を説明し、それを修正する方法があるかどうかを知りたいです (C++0x は許可されています)。ここに行きます。

コンストラクターが引数を 1 つだけ取るクラスがあり、この 1 つの引数の型がデフォルトのコンストラクターを持つ別のクラスであるとします。例えば:

struct ArgType {};

class Class
{
public:
    Class(ArgType arg);
};

スタック上に型のオブジェクトを構築しようとするとClass、あいまいさが生じます。

Class c(ArgType()); // is this an object construction or a forward declaration
                    // of a function "c" returning `Class` and taking a pointer
                    // to a function returning `ArgType` and taking no arguments
                    // as argument? (oh yeh, loli haets awkward syntax in teh
                    // saucecode)

私はそれがオブジェクトの構築だと言っていますが、コンパイラはそれが関数本体内の前方宣言であると主張しています。まだ理解していない人のために、完全に機能する例を次に示します。

#include <iostream>

struct ArgType {};
struct Class {};

ArgType func()
{
    std::cout << "func()\n";
    return ArgType();
}

int main()
{
    Class c(ArgType());

    c(func); // prints "func()\n"
}

Class c(ArgType funcPtr()) // Class c(ArgType (*funcPtr)()) also works
{
    funcPtr();
    return Class();
}

まあ、十分な例です。あまりにも反慣用的なものにすることなく、誰でもこれを回避するのを手伝ってくれますか (私はライブラリ開発者であり、人々は慣用的なライブラリが好きです)?

- 編集

どうでも。これは、ほとんどの厄介な解析のだまされています。なぜ A a(()); 仕事?.

ありがとう、sbi。

4

3 に答える 3

6

これは、「C++ で最も厄介な解析」として知られています。ここここを参照してください。

于 2010-02-16T19:31:17.140 に答える
1

「C++0x が許可されている」に基づいて、正しい答えは (おそらく) 定義を次のように変更することです。

Class c(ArgType {});

シンプルで分かりやすく、作成者ではなく、ライブラリのユーザーに完全に負担をかけます!

編集: はい、ctor が呼び出されます。C++ 0x は、初期化リストを区切る明確な方法として List-Initialization を追加します。サンプルのように誤って解析されることはありませんが、それ以外の場合、意味は括弧を使用した場合とほぼ同じです。§8.5.4/3 の 3 番目の箇条書きであるN3000を参照してください。イニシャライザ リストを 1 つの引数として受け取るように ctor を作成するか、イニシャライザ リスト内の項目を個別に ctor 引数と一致させることができます。

于 2010-02-16T19:38:04.563 に答える
1

少し単純化しましょう。

int f1();

あれは何でしょう?コンパイラ (および私) は、整数を返す関数の前方宣言だと言います。

これはどう?

int f2(double );

コンパイラ (および私) は、これは double 引数を取り、int を返す関数の前方宣言だと言います。

だからあなたはこれを試しましたか:

ClassType c = ClassType(ArgType());

説明と例については、コンストラクターに関する c++ faq lite を確認してください。

于 2010-02-16T19:41:32.233 に答える