如何从可变参数构造函数参数构造任何对象?

时间:2017-09-13 21:33:12

标签: c++ c++11 templates vector

我正在尝试制作自己的容器,我正在为我的Vector类编写一个Emplace方法。

首先,这是我的前进功能:

template<typename T>
T&& Forward(typename remove_reference<T>::Type& arg)
{
    return static_cast<T&&>(arg);
}

template<typename T>
T&& Forward(typename remove_reference<T>::Type&& arg)
{
    static_assert(!Internal::is_lvalue_reference<T>::Result);

    return static_cast<T&&>(arg);
}

它们基本上与std个相同。

现在这是我的Emplace方法:

template<typename T>
template<class... ARGS>
void MyVector<T>::Emplace(ARGS&&... args)
{
    Add(Forward<ARGS>(args)...);
}

这给了我一个错误“函数不带2个参数”,因为Add不适用于可变参数。所以我只是做到了:

template<typename T>
template<class... ARGS>
void MyVector<T>::Emplace(ARGS&&... args)
{
    if(size >= capacity)
    {
        AdaptCapacity();
    }

    data[size++] = value;
}

我应该在_data[_size++] = value;放些什么?如何使用可变参数构造任何“T”?如果我将一个Forward的调用传递给T的构造函数,它会给我带来与传递给Add相同的错误,因为'...'语法。我还能做什么?

我试过查看std :: vector,我发现的是一些似乎没有任何定义的函数_Alty_traits::construct(编译器内在函数?)

这是否意味着我不可能编写自定义的Emplace方法?

1 个答案:

答案 0 :(得分:4)

通常,如果date本身是vector<T>或其他类似的,您可以这样做:

date[size++] = T(std::forward<ARGS>(args)...);

但是,如果您正在编写自己的向量,那么data基本上会保留一些原始内存。您需要的是将对象直接构造到该原始内存中。要做到这一点,您需要新的位置:

new (date + size++) T(std::forward<ARGS>(args)...);

请注意,此展示位置新问题与使用variadics等正交;在撰写push_back时,您还需要新的展示位置。

编辑:因为您没有告诉我们date的类型或内容,并根据您在此处的评论,我假设您做了类似的事情:

data = new T[capacity];

如果这就是你所做的,那么你必须使用我给的第一个表格;使用第二种形式将是未定义的,因为您正在构建一个对象而不是另一个对象(然后您永远不能调用它的析构函数)。

但是,这不是编写向量(或任何其他通用容器)的正确方法。当一个向量抓取更多内存时,它应获取更多内存而不构造任何内容(new T[capacity]默认构造动态数组中的所有条目),在这种情况下,必须< / em>使用第二种形式。