C++を使ったbuild-in-placeの説明
要するに以下が通ると思って頂戴。
struct T { void nanika(); private: T(T const &s); }; T f() { return T(); or return(T result){ result.nanika(); } } int main() { T x = f(); T *y = new f(); return 0; }
return文は、呼び出しもとが使用する領域にインスタンスを直接作成します。コピーコンストラクタは不要です。
何も考えなくてOK。記述が面倒なMove Semanticsなんていらないね☆……いや、Unbounded_String(←std::stringと思いねえ)のようなコピーコンストラクタのある型ではコピーコンストラクタが使われてしまいますし、Ada.Containers.Vectors(←std::vectorと思いねえ)のようなリソースの移動を必要とする場合ではやっぱりMove Semanticsは有用なので、一概にどちらが良いなどと言えませんが……。
本当言うと、オブジェクトがコンストラクタ/デストラクタで自分のアドレスを外部に登録したりしないことを保証するUnaliased修飾みたいなのがあれば、ビットコピーで全てを片付けられて幸せと思うのですが、そんなものはAdaにもC++にもないです。
閑話休題。呼び出しもとが使用する領域にインスタンスを直接作成するという動作は要するにC++のコンストラクタと同じです。つまりAda2005では全ての関数がコンストラクタ化したわけで色々幸せです。
それから、Adaでは返値でオーバーロードが解決できます。つまりT a = create();とU b = create();で別々のcreateを呼び分けられます。これも色々幸せです。
それから、Adaでは多態する関数は構造体のひとつ外のスコープに書くのに加えて、受け取り側の変数のタグ(←VMTと思いねえ)に沿った多態ができます。つまりT &a;がTの派生クラスSを指している場合、a = create();はS::create();を呼んでaの指す先を作り直します。
それから、Adaではタグの文字列表現をストリームに保存できますので、実行時に文字列から実際の型を決定することも可能です。ただし文法ではなくAda.Tags.Generic_Dispatching_Constructorというライブラリを使用することになるのに加えて、AdaにはVariadic Templateがありませんので、引数が一個に固定されてしまいます。その点でメタクラスを持つ言語には劣ります。