我正在尝试制作自己的容器,我正在为我的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方法?
答案 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>使用第二种形式。