使用默认值初始化unique_ptr的向量(nullptr?)

时间:2017-08-11 09:14:14

标签: c++ vector unique-ptr

我有一个模板化函数,它接受多个元素,可能还有参数化类型的初始值。如果没有提供初始值,则假定此类型有默认构造函数。 在此函数中,我声明std::vector给定数量的元素和分配给它们的初始值。

只要模板类型不是unique_ptr

,一切都很好
#include <memory>
#include <vector>

using namespace std;


template <class T>
void define_vector(size_t size, const T& init_val=T())
{
  vector<T> sample(100, init_val);
}

int main()
{

  define_vector<int>(100);   //<-- this works

  define_vector<unique_ptr<int> >(100); //<-- this does not
  return 0;
}

据我所知,它试图复制unique_ptr这是不允许的(已删除的构造函数)。但有什么方法可以解决这个问题吗?

我当然可以定义2个版本的函数 - 一个用于,另一个没有初始值作为参数。但这是唯一的方法吗?

更新:澄清明显的误解。我知道使用not-default unique_ptr时代码没有意义/不应该编译。我想到的是以下内容。假设有一个类Foo只有显式构造函数,它将int值作为参数。因此

define_vector<Foo>(100);    //does not make sense and does not compile
define_vector<Foo>(100, Foo(42));  //makes sense and compiles.

然而:

//does not make sense and does not compile
define_vector<unique_ptr<int> > (100, std::make_unique<int>(42));
//does make sense but still does not compile
define_vector<unique_ptr<int> > (100);

那么可以在不诉诸函数重载的情况下使第二种情况发挥作用吗?

2 个答案:

答案 0 :(得分:1)

创建一个unique_ptr数组是没有意义的,其中所有指针都具有相同的值(然后它们不会唯一),但值{{1}除外}。因此,接受任意初始值的函数对nullptr无意义。

  

我当然可以定义2个版本的函数 - 一个用于,另一个没有初始值作为参数。但这是唯一的方法吗?

这是一种简单的方法,所以这是一个好方法。它甚至可能是最简单的方式,我不打算考虑是否有另一种方式。

  

我可以使用单个函数来获取初始值,或者使用默认构造函数(如果存在)

当你有C ++ 17时,这是可能的:

unique_ptr
  

问题是,是否有更好的方式?

不,我不这么认为。上面的内容不如重载,因为它允许传递初始参数,但是它会被静默忽略,而当给出非可复制类型的第二个参数时,重载方法会因为错误而失败。

答案 1 :(得分:1)

使用可变参数模板,您可以执行以下操作:

template <typename T, typename ... Ts>
void define_vector(size_t size, const Ts&... init_val)
{
    std::vector<T> sample(100, init_val...);
    // ...
}

注意:您可以添加一些SFINAE到约束init_val,如果需要,最多只能有一个arg。

然后

define_vector<int>(5);     // Call vector<int>(5) instead of your vector<int>(5, 0)
define_vector<int>(5, 42); // Call vector<int>(5, 42);

define_vector<unique_ptr<int> >(5); // Call vector<unique_ptr<int>>(5)