条件运算符+ upcast + const引用 [英] Conditional operator + upcast + const reference

查看:122
本文介绍了条件运算符+ upcast + const引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

受到此问题的启发,我尝试了以下代码:

  struct A {
virtual void doit()const = 0;
};

struct B:public A {
virtual void doit()const;
};

struct C:public A {
virtual void doit()const;
};

void
foo(bool p)
{
const A& a =(p?static_cast< const A&& static_cast< const A&>(C()));
a.doit()
}

我试过的每个编译器接受这个代码与 -Wall -Werror 并生成我想要的程序集。但是仔细阅读C ++ 03规范第12.2节(Temporaries)和第5.12节(条件运算符)后,我不确定这是否能保证工作。



那么,这是有效的代码,还是调用未定义的行为?对于C ++ 03和C ++ 11,答案是否不同?



相关规范的引用将不胜感激。



考虑:



<$>

p $ p> #include< iostream>
using namespace std;

struct A {
virtual〜A(){cout< 〜A< endl; }
virtual void doit()const = 0;
};

struct B:public A
{
〜B()override {cout< 〜B<< endl; }
void doit()const override {cout< A :: doit< endl; }
};

struct C:public A
{
〜C()override {cout< 〜C< endl; }
virtual void doit()const {cout< C :: doit< endl; }
};

void foo(bool p)
{
cout< foo(<< p<<)< endl;
const A& a =(p?static_cast< const A&>(B()):static_cast< const A&
a.doit();
}

auto main(int argc,char * argv []) - > int
{
cout<< boolalpha;

foo(true);
cout<< endl;
foo(false);
}

Coliru Viewer ,使用g ++ 4.8:

 
foo(true)
b $ b〜B

〜A

纯虚拟方法称为

终止调用时没有活动异常

bash :line 7:16922 Aborted(core dumped)./a.out

这是UB所以任何解释都可以是真的,没有看到程序集,没有看到程序集,发生了什么:




  • 构建了一个临时结构。

  • 它绑定到引用。

    这是绑定到引用的引用,因此不涉及创建新的临时或切片。

  • 临时

  • 作为其动态类型(vtable指针)的一部分,更改为 A >
  • 调用 A 中的纯虚拟。


Inspired by this question, I tried the following code:

struct A {
  virtual void doit() const = 0;
};

struct B : public A {
  virtual void doit() const;
};

struct C : public A {
  virtual void doit() const;
};

void
foo(bool p)
{
  const A &a = (p ? static_cast<const A &>(B()) : static_cast<const A &>(C()));
  a.doit();
}

Every compiler I have tried accepts this code with -Wall -Werror and generates the assembly I want. But after carefully reading the C++03 specification section 12.2 ("Temporaries") and section 5.12 ("Conditional Operator"), I am unsure whether this is guaranteed to work.

So, is this valid code, or does it invoke undefined behavior? Does the answer differ for C++03 and C++11?

Citations from relevant specifications would be appreciated.

解决方案

Oh, it's very invalid.

Consider:

#include <iostream>
using namespace std;

struct A {
    virtual ~A() { cout << "~A" << endl; }
    virtual void doit() const = 0;
};

struct B : public A
{
    ~B() override { cout << "~B" << endl; }
    void doit() const override { cout << "A::doit" << endl; }
};

struct C : public A
{
    ~C() override { cout << "~C" << endl; }
    virtual void doit() const { cout << "C::doit" << endl; }
};

void foo(bool p)
{
    cout << "foo( " << p << ")" << endl;
    const A &a = (p ? static_cast<const A &>(B()) : static_cast<const A &>(C()));
    a.doit();
}

auto main( int argc, char* argv[] ) -> int
{
    cout << boolalpha;

    foo( true );
    cout << endl;
    foo( false );
}

Output in Coliru Viewer, using g++ 4.8:

foo( true)

~B

~A

pure virtual method called

terminate called without an active exception

bash: line 7: 16922 Aborted                 (core dumped) ./a.out

It's UB so any explanation could be true, but one can be reasonably sure, without looking at the assembly, that what happens is:

  • A temporary is constructed.
  • It's bound to the reference.
    This is a reference being bound to a reference, so does not involve creation of a new temporary or slice.
  • The temporary is destroyed.
  • As part of that its dynamic type (vtable pointer) is changed to A, which is abstract.
  • The pure virtual in A is called.

这篇关于条件运算符+ upcast + const引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆