2

カスタム メモリ アロケータを作成しています。できればこのようなオブジェクト作成機能を作り、作成手順を完全に抽象化したい。

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;
}

valueas 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 にフォールバックします。

4

3 に答える 3