質問: new(_pAlloc) float; Foo(_pObj); free(_pAlloc); } return 0; } ```
回答: 結論から言うと、 C++ の規格に明記された挙動なので、問題ありません。 C++11 (N3337) の標準規格の `12.4 Destructors p16` に以下のように書かれています。 > > the notation for explicit call of a destructor can be used for any scalar type name ([expr.pseudo]). Allowing this makes it possible to write code without having to know if a destructor exists for a given type. For example, > > 参考訳: スカラの型名に対して、デストラクタの明示的な呼出しの記法を使うことができる ([expr.pseudo]) 。それを許すことによって、型に対するデストラクタがあるか否かを知らなくても、コードを書くことができる。例えば: > > For example: > > > > ``` > typedef int I; > I* p; > p->I::~I(); > > ``` > > 参考: この、スカラ型(厳密には、クラスではない型)に対する呼び出しは、「疑似デストラクタ」と呼ばれていて、 その挙動は `5.2.4 Pseudo destructor call` で定義されています。 具体的には、 `p` が評価される以外の効果は発生しません。 また、ドット演算子の左辺はスカラ型、アロー演算子の左辺はスカラ型へのポインタでなけれなりません。 上記の例にあるように、テンプレートを使わずとも、 typedef で組み込み型のキーワードに別名をつければ、明示的に呼び出すことが可能です。 `_pObj->~float();` とするとエラーになってしまう (※) のは、 float 型がスカラ型であるからではなく、 `float` が識別子ではない(キーワードである)からでしょうね。 ※: g++ (GNU C++ Compiler) ではエラーになりましたが、コンパイラーによってはエラーにならないかもしれません。 なお、ここで言うスカラ型というのは、 `3.9 Types p9` で定義されている、算術型・列挙型・ポインタ型・メンバへのポインタ型 を指します。 つまり、(構造体を含む)クラス型やスカラ型以外のもの、例えば配列型などでは、明示的なデストラクタの呼び出しの記述が行えません。 ``` #include typedef int I; typedef int A[3]; int main() { I i = 1; i.~I(); // ↑ これは可能 A a = { 0, 1, 2 }; a.~A(); // ↑ これはエラー } ``` ちなみに、 C++03 (N1577) でも、 `12.4 デストラクタ p15` で同様の内容が記載されています。 C++03 であれば、対応する JIS規格 (JISX3014) が存在するので、日本語でその内容を確認できます。