C ++ template constructor with unique_ptr parameter

When a class template contains unique_ptr for another class, the class constructor does not move unique_ptr to the new object. Using the same class, but without a template, the constructor generates an object as expected.

#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;
}
+4
source share
1 answer

This is just a typo:

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

This line should be

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

ushas already been moved from the first section main, so access in the penultimate line is not valid:

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

A fix that makes program execution .

+5
source

All Articles