我正在尝试编写自己的智能指针(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;
}
输出:
Default constructor
Destructor
Destructor
Finished
Destructor
正如您所看到的,这里有许多析构函数。在我看来,复制省略和模板构造函数之间的交互存在一些问题,但我不知道这种错误可能是什么原因。我尝试通过添加explicit
copy-constructor来解决问题,并强制编译器使用我的模板构造函数:
// After TestTemplateClass(int inState), but it's not important
explicit TestTemplateClass(const OwnType &inValue) {
std::cout << "Copy constructor" << std::endl;
}
获得下一个输出:
Default constructor
Template-copy constructor
Destructor
Template-copy constructor
Destructor
Finished
Destructor
这里看起来都不错,但它看起来不是一个干净的解决方案。还有更好的选择吗?
答案 0 :(得分:4)
(N)RVO 永远不会引入构造函数和析构函数调用之间的差异。它的设计目的主要是不可能的。
问题在于您的代码。根据语言规则,构造函数模板永远不会用于生成复制构造函数。复制构造函数永远不是模板,句点。
因此,您的类模板实际上并未声明复制构造函数,因此编译器会生成默认值(当然,它不会打印任何内容)。如果您需要在复制构造函数中进行任何特殊处理,则必须始终手动声明它。永远不会使用模板来实例化。
答案 1 :(得分:1)
您的实验表明根本没有错误:第一个版本只使用了不打印任何内容的复制构造函数,而第二个版本使用了不同的构造函数,因为您有效地禁用了它。
(它看起来像你使用的任何编译器和选项都没有做RVO)