模板类(N)调用的析构函数过多

use*_*739 3 c++ templates copy-elision c++11

我正在尝试编写自己的智能指针(C ++ 11)并使用一个问题进行堆栈,可以通过下一个示例进行解释:

#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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

Default constructor
Destructor
Destructor
Finished
Destructor
Run Code Online (Sandbox Code Playgroud)

如您所见,这里有很多析构函数。在我看来,复制省略与模板构造函数之间的交互存在一些问题,但我不知道造成此错误的原因是什么。我试图通过添加explicit复制构造函数来解决此问题,并强制编译器使用我的模板构造函数:

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

得到下一个输出:

Default constructor
Template-copy constructor
Destructor
Template-copy constructor
Destructor
Finished
Destructor
Run Code Online (Sandbox Code Playgroud)

这里看起来都不错,但是看起来并不是一个干净的解决方案。有更好的选择吗?

Rei*_*ica 5

(N)RVO 永远不会在构造函数和析构函数调用的数量之间引入差异。它旨在使这基本上不可能。

问题出在您的代码上。根据语言规则,构造函数模板永远不会用于生成副本构造函数。复制构造函数绝不是模板,句点。

因此,您的类模板实际上并未声明一个副本构造函数,因此编译器会生成默认的构造函数(当然不会显示任何内容)。如果需要在复制构造函数中进行任何特殊处理,则必须始终手动进行声明。模板永远不会用于实例化一个模板。