由于某种原因,第二种方法不起作用。
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;
}
答案 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+确实实现了它。