Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用默认值(nullptr?)初始化unique_ptr的向量_C++_Vector_Unique Ptr - Fatal编程技术网

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

C++ 使用默认值(nullptr?)初始化unique_ptr的向量,c++,vector,unique-ptr,C++,Vector,Unique Ptr,我有一个模板函数,它接受元素的数量,可能还有参数化类型的初始值。如果未提供初始值,则假定此类型有默认构造函数。 在这个函数中,我声明给定数量的元素和分配给它们的初始值的std::vector 只要模板类型不是唯一的,一切都可以: #include <memory> #include <vector> using namespace std; template <class T> void define_vector(size_t size, const

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

只要模板类型不是唯一的,一切都可以:

#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;
}
然而:

//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);
//没有意义,无法编译
定义_向量(100,std::使_唯一(42));
//确实有意义,但仍然无法编译
定义_向量(100);

那么,是否有可能在不使用函数重载的情况下使上述第二种情况工作?

创建一个
unique\u ptr
数组是没有意义的,其中所有指针都具有相同的值(那么它们就不是unique),除了值
nullptr
。因此,接受任意初始值的函数对于
unique\u ptr
来说是毫无意义的

我当然可以定义函数的两个版本——一个有初始值,另一个没有初始值作为参数。但这是唯一的办法吗

这是一个简单的方法,所以这是一个好方法。这甚至可能是最简单的方法,我也不会考虑是否还有其他方法

我可以有一个可以接受初始值的函数吗?如果存在,可以使用默认构造函数吗

使用C++17时,这是可能的:

template <class T>
void define_vector(size_t size, const T& init_val=T())
{
  vector<T> sample;
  if constexpr(is_copy_assignable<T>::value) {
      sample.resize(size, init_val);
  } else {
      assert(init_val == T());
      sample.resize(size);
  }
}
模板
void define_vector(size_t size,const t&init_val=t())
{
向量样本;
if constexpr(is_copy_assignable::value){
调整大小(大小,初始值);
}否则{
断言(init_val==T());
样本。调整大小(大小);
}
}
问题是是否有更好的方法


不,我不这么认为。上述方法不如重载方法,因为它允许传递初始参数,但会被静默忽略,而重载方法会失败,并出现错误,当为不可复制类型提供第二个参数时。

对于可变模板,您可以执行以下操作:

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

调用
define_vector(100,std::make_unique(42))的预期结果是什么?这当然是简化的示例。实际上vector是类的成员,我想在构造函数中初始化它。这并不能回答我的问题。再想一想:你对那个电话的预期结果是什么?您可能会发现,回答这个无关紧要的问题已经为您提供了原始代码无法工作的原因的答案。我希望向量
sample
,它实际上被定义为模板类的一个成员,被初始化并用默认值填充。函数
define\u vector
在现实生活中是此类类的构造函数。这仍然不能回答我的问题。对于我给出的调用,您希望向量包含什么?我要说清楚,我问这个问题不是为了让你生气。这实际上直接关系到你问题的核心,一旦你开始思考,你就有希望意识到这一点。我理解这一点。但是,请考虑这一点——假设<代码> t>代码>是一个类<代码> fo没有默认构造函数。然后在没有第二个参数的情况下调用
define\u vector
,也没有意义,也不会编译。因此,这里我们遇到了相反的情况——传递'defined'
unique\u ptr
没有意义,它不编译,这是可以的。但是复制“default”空
unique\u ptr
并没有什么错,所以可以实现吗?至于第二部分——假设代码重复。问题是是否有更好的方法?@one_two_three是的,复制
唯一的\u ptr
是错误的,即使它是空的。这是不允许的,因为
unique\u ptr
是不可复制的。我的答案是不,没有比重载更好的方法(据我所知),重载是一种非常好的方法。
template <typename T, typename ... Ts>
void define_vector(size_t size, const Ts&... init_val)
{
    std::vector<T> sample(100, init_val...);
    // ...
}
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)