c++ 投掷活动物体

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

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

查看所有标签

猜你喜欢:

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

零边际成本社会

零边际成本社会

[美]杰里米·里夫金 / 赛迪研究院专家组 / 中信出版社 / 2014-11-1 / 49.00

在这本书中,《第三次工业革命》作者杰里米•里夫金开创性地探讨了极致生产力、协同共享、产消者、生物圈生活方式等全新的概念,详细地描述了数以百万计的人生产和生活模式的转变。他认为,“产消者”正在以近乎零成本的方式制作并分享自己的信息、娱乐、绿色能源和3D打印产品。他们也通过社交媒体、租赁商、合作组织以极低或零成本的模式分享汽车、住房、服装和其他物品;学生更多地参与到基于零成本模式的开放式网络课程…… ......一起来看看 《零边际成本社会》 这本书的介绍吧!

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

各进制数互转换器

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

在线图片转Base64编码工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具