EckhardN
EckhardN

Reputation: 509

Constructor of C++ Template with unique_ptr as member fails

When a class template contains an unique_ptr to another class the constructor of the class does not move the unique_ptr into the new Object. Using the same class, but without a template the constructor generates the 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;
}

Upvotes: 4

Views: 141

Answers (1)

Columbo
Columbo

Reputation: 60989

It's 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));

us was already moved from in the first section of main, therefore the access in the penultimate line is invalid:

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

Fixing that makes the program run fine.

Upvotes: 5

Related Questions