gpt4 book ai didi

c++ - 未调用模板类复制构造函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:19:53 25 4
gpt4 key购买 nike

我的复制构造函数没有被调用,我不确定为什么。这是我的代码:

template <typename T>
class SmartPtr
{
public:
explicit SmartPtr(T *p) : m_p(p) { cout << "ctor" << endl; }
SmartPtr(const SmartPtr& p) : m_p(p.m_p) { cout << "copy ctor" << endl;}

private:
T* m_p;
};

int main()
{
SmartPtr<int> pt4 = SmartPtr<int>(new int);
}

输出只是“ctor”。看起来使用了默认的复制构造函数。如果我添加“显式”,则它不会编译,并给出错误:

"error: no matching function for call to ‘SmartPtr<int>::SmartPtr(SmartPtr<int>)’"

我在这里做错了什么?

最佳答案

这就是所谓的 Copy Elision .这是一个很好的优化,显然不需要拷贝。而不是有效地运行代码:

SmartPtr<int> __tmp(new int);
SmartPtr<int> ptr4(__tmp);
__tmp.~SmartPtr<int>();

编译器可以知道__tmp只是为了构造ptr4而存在,因此允许在拥有的内存中就地构造__tmp通过 ptr4 好像最初运行的实际代码只是:

SmartPtr<int> ptr4(new int);

请注意,您也可以告诉编译器不要这样做。例如,在 gcc 上,您可以传递 -fno-elide-constructors 选项并通过该单一更改(另外记录析构函数),现在您的代码打印:

ctor
copy ctor // not elided!
dtor
dtor // extra SmartPtr!

参见 demo .

在标准中,§12.8:

This elision of copy/move operations, called copy elision, is permitted in the following circumstances (which may be combined to eliminate multiple copies):

  • In a return statement in a function with a class return type, when ...
  • In a throw-expression, when ...
  • when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type, the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move
  • when the exception-declaration of an exception handler (Clause 15) ...

[Example:

class Thing {
public:
Thing();
~Thing();
Thing(const Thing&);
};

Thing f() {
Thing t;
return t;
}

Thing t2 = f();

Here the criteria for elision can be combined to eliminate two calls to the copy constructor of class Thing: the copying of the local automatic object t into the temporary object for the return value of function f() and the copying of that temporary object into object t2. Effectively, the construction of the local object t can be viewed as directly initializing the global object t2, and that object’s destruction will occur at program exit. Adding a move constructor to Thing has the same effect, but it is the move construction from the temporary object to t2 that is elided. —end example ]

关于c++ - 未调用模板类复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27963731/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com