自定义向量不支持 unique_ptr

Posted

技术标签:

【中文标题】自定义向量不支持 unique_ptr【英文标题】:Custom vector doesn't support unique_ptr 【发布时间】:2016-10-03 20:53:51 【问题描述】:

所以我使用了来自:https://github.com/patr0nus/Vector/blob/master/Vector.h 的自定义矢量容器

我正在尝试创建一个指向自定义 Class 对象的 unique_ptr 向量。

它曾经失败过:

错误:'std::__1::unique_ptr 类型的对象 std::__1::default_delete>' 无法分配,因为它的 复制赋值运算符被隐式删除

我通过将以下代码添加到 vector.h 来修复它:

void push_back(T&& val)
    
        resize(m_size + 1);
        m_container[m_size - 1] = std::move(val);
    

现在,问题是,我无法迭代这个向量,并且像 swap 这样的其他函数都失败了:

no matching function for call to 'swap'
        swap(*__x4, *__x5);
candidate template ignored: could not match 'tuple' against 'unique_ptr'
swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)

我需要一些关于如何解决这些问题的指导。

【问题讨论】:

这个向量似乎只用于 POD 类型。 使用std::vector 是解决方案。为什么你首先需要这个定制的?实现的问题是它绝对要求 T 是 CopyConstructible,而 std::unique_ptr 却不是。 嗯.....为什么不直接使用 std::vector? 请提供minimal reproducible example。 @SomeandroidProgrammar 不能由 来制作一个最小、完整且可验证的示例。这取决于你。 【参考方案1】:

您不能将patr0nus/Vector 与非 POD 类型一起使用。原因很简单:它在很多地方使用memcpy,并且要求类型是复制构造的。

将它与其他任何非 POD 一起使用实际上是未定义的行为。不要将该向量用于非 POD 类型。没有办法解决。

您可能知道,您可以使用定义明确的实现,该实现尊重一组精确的要求,并且可能比向量实现更优化:std::vector

如果您有一些内存或分配限制,您可以实现自定义分配器。

【讨论】:

【参考方案2】:

补充给出的答案,由于您的向量类仅适用于 POD 类型,因此确保您仅使用 POD 类型的方法是使用 std::is_pod 函数和 static_assert。使用这些 C++ 工具将禁止创建违反​​ POD 要求的程序。

当你构造向量时,你可以在这些函数中进行测试:

#include <algorithm>
//...
template<typename T>
class Vector

   Vector(int initialSize = 1)
   
      static_assert(std::is_pod<T>(), "Sorry, only POD types are allowed");
     //...
   

    Vector(const Vector &source)
    
      static_assert(std::is_pod<T>(), "Sorry, only POD types are allowed");
      //...
    
    //...
;

这样可以确保如果有人这样做:

Vector<std::string> sV;

将显示编译器错误,而不是代码编译并导致您现在看到的问题。

【讨论】:

is_pod 可转换为 bool,因此只需 static_assert(std::is_pod&lt;T&gt;, "blah") 即可。此外,您可以在类的顶部断言一次。 :)【参考方案3】:

在 resize() 函数中你有:


...
            m_capacity = size * 2;//The new capacity is double of the size.
            T* oldPtr = m_container;
            m_container = (T*)malloc(m_capacity * sizeof(T));//Allocate the new container.
            memcpy(m_container, oldPtr, m_size * sizeof(T));//Copy the elements.
            destory(oldPtr, m_size);//Destory the old container.
            free(oldPtr);
...

所以你需要把 POD(plain old data)元素放到你的向量中:What are POD types in C++?

【讨论】:

以上是关于自定义向量不支持 unique_ptr的主要内容,如果未能解决你的问题,请参考以下文章

R语言使用caret包的train函数构建支持向量机SVM模型模型调优自定义设置trainControl函数和tuneLength参数

R语言编写自定义函数计算分类模型评估指标:准确度特异度敏感度PPVNPV数据数据为模型预测后的混淆矩阵比较多个分类模型分类性能(逻辑回归决策树随机森林支持向量机)

2.1、支持向量机(线性可分定义)

如何通过使用自定义构造函数而不调用析构函数来创建具有初始大小的向量? [复制]

C++ - 在自定义数据类型向量中按值匹配和替换元素

机器学习实践:基于支持向量机算法对鸢尾花进行分类