C++ 在编译时使_唯一错误

C++ 在编译时使_唯一错误,c++,stl,smart-pointers,C++,Stl,Smart Pointers,我刚刚开始学习智能指针 必须将旧代码更改为现代c++ 当我编译下面的代码行(原始代码的示例)时,我遇到以下错误 #包括 #包括 使用名称空间std; 体类型 { int-id; 浮点数; }; auto main()->int { auto Student1=make_unique(1,5.5); //auto Student1=make_unique(1);//工作正常 //auto Student2=unique_ptr{new Student{1,22.5};//有效 cout-----

我刚刚开始学习智能指针

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

当我编译下面的代码行(原始代码的示例)时,我遇到以下错误

#包括
#包括
使用名称空间std;
体类型
{
int-id;
浮点数;
};
auto main()->int
{
auto Student1=make_unique(1,5.5);
//auto Student1=make_unique(1);//工作正常
//auto Student2=unique_ptr{new Student{1,22.5};//有效
cout-----已启动生成:项目:ConsoleApplication4,配置:调试Win32------
1> Source.cpp
1> c:\program files(x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.10.25017\include\memory(2054):错误C2661:'Student::Student':没有重载函数包含两个参数
1> c:\users\hsingh\documents\visual studio 2017\projects\consoleapplication4\consoleapplication4\source.cpp(12):注意:请参阅正在编译的函数模板实例化“std::unique_ptr std::make_unique(int&,double&)”的参考
1> 与
1>        [
1> _Ty=学生
1>        ]
1> 已完成生成项目“ConsoleApplication4.vcxproj”--失败。
======生成:0成功,1失败,0最新,0跳过==========
我试图研究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)...));
}
//注意:此实现不会对数组类型禁用此重载
模板
std::unique_ptr使_唯一(Args&&…Args)
{
返回std::unique_ptr(新的T(std::forward(args)…);
}
所以我的问题是(现在我要做的是直接使用unique_ptr)

  • 如何使用make_unique使其工作

  • 我可以对STL中的make_unique实现做哪些更改以使其工作

  • 回答了几个问题后 新增问题3

    3.通过构造函数使用make_unique或直接使用unique_ptr的最佳方法是什么

    unique_ptr<Student>{ new Student{1,22.5} }
    
    unique_ptr{新学生{1,22.5}
    

    我更喜欢后者,因为不需要定义构造函数。请确实建议基本上,
    std::make_unique
    将其参数转发给类型为
    T
    的构造函数。但是类
    Student
    中没有接受
    int
    double
    的构造函数。您可以添加一个:

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

    使代码正常工作。

    不幸的是,
    make_unique
    不执行直接列表初始化。如果查看其说明,您将看到以下语句:

    构造非数组类型T。参数args传递给 构造函数。此重载只参与重载 如果T不是数组类型,则解析。该函数等效于: 唯一的ptr(新T(标准::转发(args)…)

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

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

    但是make_unique并没有调用这个表单,所以这就是它失败的原因。有一个建议让它这样工作:

    在原始stl上有什么可以做的,这样它就不会抱怨或者不需要构造它在没有构造函数unique的情况下工作了吗{new Student{1,22.5}@HariomSingh我没有看到任何其他选项,除了
    unique{newstudent{…}
    ,就像你在问题中提到的。它使用聚合初始化,所以它可以工作。但是没有办法将聚合初始化与
    std::make_unique
    一起使用。Rokyan任何建议都需要更改哪些内容以使_唯一,这不需要像unique一样的构造函数。\u ptr{new Student{1,22.5}我认为
    make_unique({1,5.5});
    应该编译。@mannish不,聚合初始化不是这样工作的。
    auto* p = new Student{2, 3};