C++unique_ptr作为成员的模板的构造函数失败

Constructor of C++ Template with unique_ptr as member fails

本文关键字:构造函数 失败 成员 ptr C++unique      更新时间:2023-10-16

当类模板包含对另一个类的unique_ptr时,该类的构造函数不会将unique_ptr移动到新对象中。使用相同的类,但没有模板,构造函数按预期生成对象。

#include <iostream>
class test1{
public:
    std::string s_;
    test1(std::string s):s_(s){};
};
class testu{
public:
    std::unique_ptr<test1> us_;
    testu(std::unique_ptr<test1> us):us_(std::move(us)){};
};
template <int i>
class testt {
public:
    std::unique_ptr<test1> us_;
    testt<i>(std::unique_ptr<test1> us):us_(std::move(us)){};
};
template class testt<0>;
int main(int argc, const char * argv[]) {
    //without template
    std::unique_ptr<test1> us(new test1("test"));
    testu* t1=new testu(move(us));
    std::cout<<t1->us_->s_<<"n";
    //with template the constructor fails!
    std::unique_ptr<test1> ust(new test1("test"));
    testt<0>* t2=new testt<0>(std::move(us));
    std::cout<<t2->us_->s_<<"n";  //crash!
    return 0;
}
这只是

一个错字:

testt<0>* t2 = new testt<0>(std::move(us));

这一行应该是

testt<0>* t2 = new testt<0>(std::move(ust));

us 已经在 main 的第一部分中移动,因此倒数第二行的访问无效:

std::cout<<t2->us_->s_<<"n"; 
//             ^^^
//              | Was already moved from, access causes UB

修复使程序运行良好