模板化 'strdup()'?

A templated 'strdup()'?

template<typename T>
static T *anydup(const T *src, size_t len) {
    T *ptr = malloc(len * sizeof(T));
    memcpy(ptr, src, (len * sizeof(T)));
    return ptr;
}

这样合适吗?当使用 int、long 等时,我可以预期会出现任何错误吗?我是泛型编程的新手,正在尝试了解更多信息。

不,这不合适!当你在 C++ 代码中出现 malloc() 时,你应该变得非常怀疑:

  • malloc() 分配内存,但没有正确创建对象。使用此类内存的唯一方法是使用新的放置。
  • memcpy() 不遵守 C++ 对象的复制语义。这只能用于普通可复制 类。我会导致很难在其他地方找到错误(浅拷贝和其他导致 UB 的可怕事情)。

对于像 char、int、double 这样的基本类型,它可以工作。但不适用于更复杂的类型。


备选方案 1:调整您的代码以正确创建和复制对象

template<typename T>
T *anydup (const T *src, size_t len) {
    T *ptr = new T[len];                        // requires that T has a default constructor
    copy (src, src+len, ptr);                   // requires that T is copyiable
    return ptr;
}

注意:如果用户忘记删除数组,有内存泄漏的风险,如果用户没有使用,则有UB delete[]!为避免这种情况,您可以选择返回 unique_ptr<T[]>


备选方案 2:摆脱数组和指针以及内存噩梦:使用向量!

template<typename T>
vector<T> anydup (const vector<T> src) {
    vector<T> v(len);                        // requires that T has a default constructor
    copy (src.cbegin(), src.cend(), v);      // requires that T is copyable
    return v;
}

您可以考虑按照 Remy Lebeau 和 FDinoff 在评论中的建议,在函数中或直接在使用代码中使用复制构造函数来创建向量。

如果你在使用代码中直接使用copy(),你很快就会发现还有copy_if()copy_backwards()和其他一些不错的<algorithms>可以视情况使用。