编译时make_unique错误

时间:2017-08-02 21:47:09

标签: c++ stl smart-pointers

我刚开始学习智能指针 stl::make_unique

必须将旧代码更改为现代c ++

编译下面的代码行(原始代码示例)

时出现以下错误
#include <memory>
#include <iostream>

using namespace std;
struct Student
{
    int  id;
    float Score;
};
auto main()->int
{
    auto Student1 = make_unique<Student>(1, 5.5);
    //auto Student1 = make_unique<int>(1);  //Works perfectly
    //auto Student2 = unique_ptr<Student>{ new Student{1,22.5} }; //Works 
    cout << "working";
    return 0;
}

1>------ Build started: Project: ConsoleApplication4, Configuration: Debug Win32 ------
1>Source.cpp
1>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.10.25017\include\memory(2054): error C2661: 'Student::Student': no overloaded function takes 2 arguments
1>c:\users\hsingh\documents\visual studio 2017\projects\consoleapplication4\consoleapplication4\source.cpp(12): note: see reference to function template instantiation 'std::unique_ptr<Student,std::default_delete<_Ty>> std::make_unique<Student,int,double>(int &&,double &&)' being compiled
1>        with
1>        [
1>            _Ty=Student
1>        ]
1>Done building project "ConsoleApplication4.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

我试着看看make_unique实现看起来应该有用。看看上面的网站和可能的实现是

// note: this implementation does not disable this overload for array types
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

所以我的问题是(现在解决的问题是直接使用unique_ptr)

  1. 如何使用make_unique

  2. 使其正常工作
  3. 我可以对STL中的make_unique实现进行哪些更改以使其正常工作

  4. 经过几次回答 添加了问题3

    3.使用make_unique与构造函数或直接使用unique_ptr

    最好
    unique_ptr<Student>{ new Student{1,22.5} }
    

    我更喜欢后者,因为不需要定义构造函数。请做建议

2 个答案:

答案 0 :(得分:4)

不幸的是,make_unique不执行直接列表初始化。如果你查看它的描述here,你会看到以下声明:

  

构造一个非数组类型T.参数args传递给   T的构造函数。这个重载只参与重载   如果T不是数组类型,则为分辨率。该功能相当于:   unique_ptr(新T(std :: forward(args)...)

你的班级没有一个接受两个参数的构造函数。但它是一个聚合,并且可以使用聚合初始化来构造,如第二个示例所示:

auto* p = new Student{2, 3};

但是make_unique没有调用这个表单,所以这就是它失败的原因。有人建议让它像这样工作:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4462.html

答案 1 :(得分:1)

基本上,std::make_unique<T>将其参数转发给类型为T的构造函数。但是,Student类中没有构造函数接受intdouble。您可以添加一个:

struct Student
{
    Student(int id, float Score) : id(id), Score(Score) {}
    int  id;
    float Score;
};

使代码有效。