16

C# では、次のように記述できます。

    class AnyThing<T>
    {
        static public T Default = default(T);
    }

    static void Main ()
    {
        int i = AnyThing<int>.Default;
        Console.WriteLine (i==0);
        string s = AnyThing<string>.Default;
        Console.WriteLine (s == null);

    }

私は C++ でテンプレート クラスのような辞書を作成するつもりです。指定されたキーが見つからない場合、dict がジェネリック TVal 型の既定値 (0 アウト) を返すようにしたいと考えています。C# では default(T) コンストラクトが役に立ちますが、C++ では同じことを行う適切な方法がわかりません。

私は試してみましたがT obj = {}T* obj = {}gcc4.7 でうまく動作します。それが言語仕様で定義された構文であるかどうか、このようなコードが移植可能なクロスコンパイラとプラットフォームになるかどうかはわかりません。私の疑いで私を助けてください!前もって感謝します!

PS:

~~~~~~~~~~

呼び出し可能なデフォルト ctor を持たないものであっても、テンプレートが任意のタイプのデフォルト (ゼロアウト) 値を取得するようにするために、次のメカニズムを採用しました (avakar の回答に触発されました):

template<class T>
struct AnyThing
{
    static const T& Default ;
private:
    static const char temp[sizeof(T)];
};

template<class T> const char AnyThing<T>::temp[] = {};
template<class T> const T& AnyThing<T>::Default =  *(T*)temp;

struct st
{
    double data;
    st()=delete;
};

int main()
{
    cout << (int)AnyThing<char*>::Default<<endl;    //0
    cout << AnyThing<int>::Default<<endl;       //0
    cout <<AnyThing<st>::Default.data<<endl;        //0
}

見栄えは悪いですが、何も問題が発生することはありません。ゼロ化されたオブジェクトは単なる空のメモリの塊に過ぎないからです。私が間違っている?

4

5 に答える 5

32

C++ にはdefault、C# のようなキーワードはありません。class-type の値のデフォルトコンストラクタによる初期化は失敗するため、デフォルトコンストラクタがprivate. C# では、デフォルト コンストラクターが private の場合、class-type は であるためnull、 class-type の値は に初期化されreference-typeます。

初期化 by{}は、言語仕様で定義されています。C++11です。C++03 では、使用する必要があります

T obj = T();

コメントでbames53が指摘しているように、初期化T*する場合は使用する必要があります

C++11 より前。

T* obj = 0;

また

T* obj = NULL;

C++11 で。

T* obj = {};

また

T* obj = nullptr;
于 2012-09-27T06:43:41.430 に答える
8

「The C++ Programming Language, Third Edition by Bjarne Stroustrup」から文字通り引用:

見積もりを開始

4.9.5 初期化 [dcl.init]

オブジェクトにイニシャライザが指定されている場合、そのイニシャライザによってオブジェクトの初期値が決定されます。初期化子が指定されていない場合、グローバル (§4.9.4)、名前空間 (§8.2)、またはローカル静的オブジェクト (§7.1.2、§10.2.4) (まとめて静的オブジェクトと呼ばれる) は、適切な型の 0 に初期化されます。 . 例えば:

int a;  // means int a=0;
double d; // meands d=0;

ローカル変数 (自動オブジェクトと呼ばれることもあります) とフリー ストアで作成されたオブジェクト (動的オブジェクトまたはヒープ オブジェクトと呼ばれることもあります) は、既定では初期化されません。例えば:

void f()
{
   int x;   // x does not have a well-defined value
   // . . . 
}

配列と構造体のメンバーは、配列または構造体が静的であるかどうかに応じて、デフォルトで初期化されるかどうかに依存します。ユーザー定義型には、デフォルトの初期化が定義されている場合があります (§10.4.2)。

より複雑なオブジェクトでは、初期化子として複数の値が必要です。これは、配列 (§5.2.1) と構造体 (§5.7) の C スタイルの初期化のために { と } で区切られた初期化子リストによって処理されます。

コンストラクターを持つユーザー定義型の場合、関数スタイルの引数リストが使用されます (§2.5.2、§10.2.3)。宣言内の空の括弧 () のペアは、常に「関数」を意味することに注意してください (§7.1)。例えば:

int a[] = {1,2};    // array initializer
Point z(1,2);       // function-style initializer (initialization by constructor)
int f();            // function declaration

見積もりを終了

したがって、そのタイプの静的オブジェクトから任意のタイプのデフォルト値を取得できます。

static T defaultT; // `defaultT' has de default value of type T
于 2012-09-27T07:03:19.190 に答える
3

コピー コンストラクターがない場合、ForEveR の回答はT機能しません。C++03 では、一般的で洗練された変数をゼロで初期化する方法はありません。あとは次のトリックです。

T temp[1] = {};
T & obj = temp[0];

ここで、temp[0]はゼロで初期化されてから にバインドされobjます。コピー コンストラクターは必要ありません。

于 2012-09-27T07:13:09.597 に答える