カスタム メモリ アロケータを作成しています。できればこのようなオブジェクト作成機能を作り、作成手順を完全に抽象化したい。
template<typename T>
class CustomCreator
{
virtual T& createObject(T value) __attribute__((always_inline))
{
T* ptr = (T*)customAlloc();
new (ptr) T(value);
return *ptr;
}
}
しかし、これはコピーを引き起こします。この場合、コピーを強制的に排除する方法はありますか?
これが私の現在のテストコードです。
#include <iostream>
struct AA
{
inline static void test(AA aa) __attribute__((always_inline))
{
AA* ptr = new AA(aa);
delete ptr;
}
AA(AA const& aa)
{
printf("COPY!\n");
}
AA(int v)
{
printf("CTOR!\n");
}
};
int main(int argc, const char * argv[])
{
AA::test(AA(77));
return 0;
}
value
as T&
, T const&
,T&&
を渡そうとしましたT const&&
が、それでもコピーされます。オプティマイザーが関数フレームを削除すると予想していたので、関数パラメーターを R 値に推定できますが、まだCOPY!
メッセージが表示されます。
C++11のフォワーディングテンプレートも試してみましたが、仮想関数にできないので使えませんでした。
私のコンパイラは、Xcode に含まれている Clang です。(clang-425.0.28) また、最適化レベルは に設定されてい-Os -flto
ます。
更新 (後で参照するため)
追加のテストを作成し、生成された LLVM IR をclang -Os -flto -S -emit-llvm -std=c++11 -stdlib=libc++ main.cpp;
オプションでチェックしました。私が観察できることは次のとおりです。(1)関数フレームは常に削除できます。(2) 大きなオブジェクト (4096 バイト) が値渡しされた場合、削除されませんでした。(3) を使用して r 値参照を渡すstd::move
とうまくいきます。(4) move-constructor を作成しない場合、コンパイラはほとんどの場合 copy-constructor にフォールバックします。