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

How to construct any object from variadic constructor parameters?

本文关键字:参数 任何 对象 构造函数 变参      更新时间:2023-10-16

我正在尝试制作自己的容器,并且正在为我的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 方法?

通常,如果date本身是vector<T>或类似的东西,你可以这样做:

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

但是,如果您正在编写自己的向量,那么data基本上拥有一些原始内存。您需要的是将对象直接构造到该原始内存中。为此,您需要放置新的:

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

请注意,此放置新问题与使用可变参数等正交;在编写push_back时也需要放置新位置。

编辑:因为你没有告诉我们date的类型或内容,并且根据你在这里的评论,我假设你做了这样的事情:

data = new T[capacity];

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

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