c++ 投掷活动物体

栏目: C++ · 发布时间: 6年前

内容简介:http://stackoverflow.com/questions/6352438/throwing-movable-objects本站文章除注明转载外,均为本站原创或编译转载请明显位置注明出处:c++ 投掷活动物体

我注意到,当抛出的类型是可移动的时候,MSVC和g如何处理临时异常对象的创建,这一点略有不同.狩猎这些引起了额外的问题.

在进一步之前,这里是我的问题的核心:在复制/移动精灵的缺点中,标准人员是否说明如何创建临时异常对象?目前,我能做的最好的是从15.1 / 3以下引用:

A throw-expression initializes a temporary object, called the exception object, the type of which is determined by removing any top-level cv-qualifiers from the static type of the operand of throw and adjusting the type from array of T or function returning T to pointer to T or pointer to function returning T”, respectively.

我猜这个答案被埋在别的语言的某个地方,定义了一个表达式的类型,以及对象的初始化,但是我没有运气拼接在一起.当抛出一个对象时,异常对象是否得到(a)复制构造,(b)适当地移动构造,否则复制构造,或者(c)以实现定义的方式初始化?

请考虑以下代码:

#include <iostream>
using std::cout;
using std::cin;
using std::endl;

struct Blob {
  Blob() { cout << "C" << endl; }
  Blob(const Blob&) { cout << "c" << endl; }
  Blob(Blob&&) { cout << "m" << endl; }
  Blob& operator =(const Blob&) { cout << "=" << endl; return *this; }
  Blob& operator =(Blob&&) { cout << "=m" << endl; return *this; }
  ~Blob() { cout << "~" << endl; }

  int i;
};

int main() {
  try {
     cout << "Throw directly: " << endl;
     throw Blob();
  } catch(const Blob& e) { cout << "caught: " << &e << endl; }
  try {
     cout << "Throw with object about to die anyhow" << endl;
     Blob b;
     throw b;
  } catch(const Blob& e) { cout << "caught: " << &e << endl;  }
  {
    cout << "Throw with object not about to die anyhow (enter non-zero integer)" << endl;
    Blob b;
    int tmp;
    cin >> tmp; //Just trying to keep optimizers from removing dead code
    try {
      if(tmp) throw b;
      cout << "Test is worthless if you enter '0' silly" << endl;
    } catch(const Blob& e) { cout << "caught: " << &e << endl;  }
    b.i = tmp;
    cout << b.i << endl;
  }
}

这是在 ideone 上重新创建的.正如你所希望看到的,gcc通过ideone在第一种情况下创建了Blob对象,并在第二种情况下移动.结果总结如下,指针值替换为标识符.

Throw directly: 
C {A}
caught: {A}
~ {A}
Throw with object about to die anyhow
C {A}
m {B} <- {A}
~ {A}
caught: {B}
~ {B}
Throw with object not about to die anyhow (enter non-zero integer)
C {A}
m {B} <- {A}
caught: {B}
~ {B}
2
~ {A}

在MSVC2010中相同的代码,无论优化设置如何,结果是一样的,除了两个动作是副本.这是最初引起我注意的区别.

我假设的第一个测试是罚款;其经典版复印.

在第二个测试中,gcc的行为方式与我预期的一样.临时Blob被视为一个x值,异常对象由它移动构造.但是我不知道编译器是否需要识别原始的Blob是否到期;如果不是,则MSVC在复制时正常运行.因此,我的原始问题:标准授权在这里发生了什么,还是只是执行定义的行为继承异常处理的一部分?

第三个测试正好相反:MSVC行为我的直觉要求. gcc选择从b移动,但是b仍然存在,这在我处理抛出的异常之后继续使用它的事实证明了这一点.显然,在这个微不足道的例子中,移动或复制对b本身没有任何影响,但是当考虑重载分辨率时,肯定不允许编译器查看.

显然,复制/移动检测的存在使得这个简单的测试很难推广,但更大的问题是,编译器可能不会简单[特别是在第三次测试的gcc和一般的MSVC的情况下].

注意这完全是为了学术目的;我几乎不会抛出任何东西,除了一个临时的,这两个编译器构造在任何地方,我相当确定行为是允许的.

移动行为符合案例2,但不符合案例3.参见12.8 [class.copy] / p31:

When certain criteria are met, an

implementation is allowed to omit the

copy/move construction of a class

object, even if the copy/move

constructor and/or destructor for the

object have side effects. …

  • in a throw-expression, when the operand is the name of a non-volatile

    automatic object (other than a

    function or catch-clause parameter)

    whose scope does not extend beyond the

    end of the innermost enclosing

    try-block (if there is one), the

    copy/move operation from the operand

    to the exception object (15.1) can be

    omitted by constructing the automatic

    object directly into the exception

    object

上面没有定义何时可以隐式地移动对象.但是它确实定义了复制/移动检查是否合法.当隐含的移动是合法的时候,你必须参考同一节中的第32段:

32 When the criteria for elision of a  copy operation are met or would be met  save for the fact that the source  object is a function parameter, and  the object to be copied is designated  by an lvalue, overload resolution 

本段解释说,当复制/移动检测是合法的时候,过载解决会发生两次:

>首先假设lvalue是决定什么构造函数被调用或被删除的值.

>如果1)失败,则以参数作为左值重复重载解析.

这具有从最差到最差产生移动语义层次结构的效果:

>如果你可以去施工,就这样做.

>否则,如果你可以移动对象,这样做.

>否则可以将对象复制出来,这样做.

>否则发出诊断.

请注意,这些本质上是与普通返回本地堆栈对象相同的规则.

http://stackoverflow.com/questions/6352438/throwing-movable-objects

本站文章除注明转载外,均为本站原创或编译

转载请明显位置注明出处:c++ 投掷活动物体


以上所述就是小编给大家介绍的《c++ 投掷活动物体》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

精彩绝伦的CSS

精彩绝伦的CSS

[美] Eric A. Meyer / 姬光 / 人民邮电出版社 / 2012-7 / 49.00元

内容简介: 打造现代布局的专业技术 本书远非只是介绍基础知识,它不仅全面细致地讲解布局与效果,而且展望了HTML5和CSS3的未来。业内很少有人能像Eric A. Meyer一样详细阐明CSS,他在本书中深入分析了普遍适用的实用技术,讲解了如何选用正确的工具、如何通过jQuery使用CSS效果和CSS3技术。 本书主要内容如下: 显示或隐藏元素 通过XHTML为bod......一起来看看 《精彩绝伦的CSS》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具