66

C++ では、次のコードでコンパイラ エラーが発生します。

void destruct1 (int * item)
{
  item->~int();
}

このコードはほぼ同じです。int を別の型に typedef すると、魔法のようなことが起こります。

typedef int myint;

void destruct2 (myint * item)
{
  item->~myint();
}

2 番目のコードが機能するのはなぜですか? int は型定義されているという理由だけでデストラクタを取得しますか?

なぜこれをやりたいのか疑問に思っている場合: これは、C++ コードのリファクタリングに由来します。標準のヒープを削除し、自作のプールに置き換えます。これには、placement-new とデストラクタを呼び出す必要があります。プリミティブ型のデストラクタを呼び出すのは役に立たないことはわかっていますが、後で POD を実際のクラスに置き換える場合に備えて、コード内にデストラクタが必要です。

裸の int は機能しないが、typedef の int は機能することがわかったのは、かなりの驚きでした。

ところで-テンプレート関数を含むソリューションがあります。テンプレート内で typedef するだけで、すべて問題ありません。

4

1 に答える 1

105

これが、コードがジェネリック パラメーターに対して機能する理由です。コンテナ C を考えてみましょう:

template<typename T>
struct C {
    // ...
    ~C() {
        for(size_t i = 0; i<elements; i++)
            buffer[i].~T();
    }
};

組み込み型に特殊なケースを導入するのは煩わしいでしょう。したがって、C++ では、T がたまたま に等しくなったとしても、上記を実行できますint。聖なる基準は次のように述べてい12.4 p15ます。

デストラクタの明示的な呼び出しの表記法は、任意のスカラー型名に使用できます。これを許可すると、特定の型にデストラクタが存在するかどうかを知らなくてもコードを記述できます。

プレーンな int と typedef された int の使用の違いは、それらが構文的に異なることです。ルールは、デストラクタ呼び出しでは、 の後のもの~は型名です。intはそのようなものではありませんが、typedef-name はそうです。で調べてください7.1.5.2

于 2009-01-19T02:05:09.290 に答える