jeudi 12 mars 2015

Too many destructors called on template classes (N)RVO optimization

I'm trying to write own Smart Pointers (C++11) and stacks with one problem, that can be explained by next example:



#include <iostream>

template<typename T_Type>
class TestTemplateClass {
private:
T_Type _state;

public:
TestTemplateClass() : _state() {
std::cout << "Default constructor" << std::endl;
}

TestTemplateClass(int inState) : _state(inState) {
std::cout << "State constructor" << std::endl;
}

template<typename T_OtherType>
TestTemplateClass(const TestTemplateClass<T_OtherType> &inValue) {
std::cout << "Template-copy constructor" << std::endl;
}

template<typename T_OtherType>
void operator = (const TestTemplateClass<T_OtherType> &inValue) {
std::cout << "Operator" << std::endl;
}

~TestTemplateClass() {
std::cout << "Destructor" << std::endl;
}
};

TestTemplateClass<int> createFunction() {
return TestTemplateClass<int>();
}

int main() {
TestTemplateClass<int> theReference = createFunction();
std::cout << "Finished" << std::endl;
return 0;
}


output:



Default constructor
Destructor
Destructor
Finished
Destructor


As you can see, there are to many destructors here. In my mind, it's some problem with interaction between copy elision and template-constructor, but I don't know what may be the reason of such bug. I tried to fix the problem by adding explicit copy-constructor and force compiler use my template-constructor:



// After TestTemplateClass(int inState), but it's not important
explicit TestTemplateClass(const OwnType &inValue) {
std::cout << "Copy constructor" << std::endl;
}


got next output:



Default constructor
Template-copy constructor
Destructor
Template-copy constructor
Destructor
Finished
Destructor


Here all looks good, but it doesn't look like a clean solution. Are there better alternatives?


Aucun commentaire:

Enregistrer un commentaire