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++ 投掷活动物体》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

刘大猫的财富之旅

刘大猫的财富之旅

刘欣、刘大猫 / 新华出版社 / 2017-7-21 / 58.00元

作者刘大猫是一名90后的互联网连环创业者,26岁的他通过互联网创业收获到了财富,不仅仅是物质财富,还有认知的财富。 与其他创业类书籍不通的是,这本书非常真实,务实。书中没有任何大道理鸡汤,作者用平实的语言记录了创业以来遇到的种种事情,变化,困境,以及阶段性的成绩,记录了作者务实,鲜活的创业青春。一起来看看 《刘大猫的财富之旅》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具