C ++ 11构造到位混乱

时间:2015-01-17 22:55:41

标签: c++ c++11

我正在尝试将矢量用作自定义存储容器的一部分。我想在向容器添加对象时避免任何临时性,并且我想手动构建对象以前的free对象。如何在不创造临时性的情况下做到这一点?

代码:

struct Mesh
{
    float data;

    Mesh(float a) : data(a)
    {
    }
};


template<typename T>
class IDStorage
{
public:
    template <typename... Arguments>
    void AddItem(Arguments&&... args)
    {
        if (!mFreeIndices.empty())
        {
            const uint32_t freeIndex = mFreeIndices.back();
            mFreeIndices.pop_back();

            // mItems[freeIndex] = Item(0, 1, args...);     NOPE - I want to avoid this temporary!
            // mItems[freeIndex].Item(0, 1, args...);   NOPE
            // new (&mItems[freeIndex]) Item(0, 1, args...);     NOPE
            // How can I avoid a temporary in this case?
        }
        else
            mItems.emplace_back(0, 1, args...);
    }

    void FreeItem(uint32_t index)
    {
        mFreeIndices.push_back(index);
        // ignore destructor
    }


private:
    struct Item {
        uint32_t mIndex;
        uint32_t mVersion;
        T mItem;

        template <typename... Arguments>
        Item(uint32_t index, uint32_t version, Arguments&&... args) : mIndex(index), mVersion(version), mItem(args...)
        {
        }
    };

    std::vector<Item> mItems;
    std::vector<uint32_t> mFreeIndices;
};

int _tmain(int argc, _TCHAR* argv[])
{
    IDStorage<Mesh> meshStorage;
    meshStorage.AddItem(1.0f);
    meshStorage.FreeItem(0);
    meshStorage.AddItem(2.0f);

    return 0;
}

1 个答案:

答案 0 :(得分:1)

你可以这样做:

template <typename... Arguments>
void AddItem(Arguments &&... args)
{       
    if (!mFreeIndices.empty())
    {
        const uint32_t freeIndex = mFreeIndices.back();
        mFreeIndices.pop_back();

        // this doesn't create a temporary          
        //mItems[freeIndex].mIndex = 0;
        //mItems[freeIndex].mVersion = 1;
        mItems[freeIndex].mItem = T(args...);
    }
    else
    {
        mItems.emplace_back(0, 1, args...);
    }
}