使用ternery表达式返回引用会导致运行时错误

时间:2016-12-01 17:48:04

标签: c++ c++11 visual-c++

由于某种原因,第二种方法不起作用。

concurrency::event<void( event_data& ), codec_cvt> &get_event( const string_type &event )
{
        auto it = events_.find( event );
        if ( it == events_.end( ) )
            throw /* exception */;
        return *it->second;
}

但是,使用我的preffered语法的这个方法是返回临时的地址。什么时候应该完全正确?

concurrency::event<void( event_data& ), codec_cvt> &get_event( const string_type &event )
{
    auto it = events_.find( event );
    return it != events_.end( ) ?
        *it->second :
        throw;
 }

1 个答案:

答案 0 :(得分:2)

在C ++ 14之前,标准规定表单false ? throw 1 : x的表达式的结果是x而不是x本身的副本(从技术上讲,它应用左值 - { - 1}}上的-r-value,数组到指针和函数到指针的转换以产生prvalue。 N3337 [expr.cond]/2

  

如果第二个或第三个操作数的类型为x,那么   左值到右值([conv.lval]),数组到指针([conv.array]),和   执行函数到指针([conv.func])标准转换   在第二和第三个操作数上,以下之一应该成立:

     
      
  • 第二个或第三个操作数(但不是两个)是 throw-expression ([except.throw]);结果是另一个的类型,并且是一个prvalue。
  •   
  • [...]
  •   

Core issue 1560改变了这一点:

  

glvalue作为条件表达式的一个操作数出现   另一个操作数是一个throw-expression被转换为a   prvalue,无论条件表达式如何使用:

     

[...]

     

这似乎是无偿和令人惊讶的。

和段落now reads

  

如果第二个或第三个操作数的类型为void,则其中一个   以下内容:

     
      
  • 第二个或第三个操作数(但不是两个)是(可能带括号的) throw-expression ([expr.throw]);结果是   另一种的类型和价值类别。 条件表达式是   如果该操作数是位字段,则为位字段。
  •   
  • [...]
  •   

MSVC还没有开始实施修复程序。 Clang 3.5+确实实现了它。