三元运算符可以抛出异常吗? [英] Can an exception be thrown from the ternary operator?

查看:351
本文介绍了三元运算符可以抛出异常吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有时方便,甚至有必要有一个只有一个语句的函数(当返回 constexpr 时,这是必要的)。如果需要检查条件并且只允许一个语句,则条件运算符是唯一的选项。在错误的情况下,从条件运算符抛出异常是很好的,例如:

Sometimes it is convenient or even necessary to have a function which just one statement (it is necessary when returning a constexpr). If a condition needs to be checked and only one statement is allowed, the conditional operator is the only option. In case of an error it would be nice to throw an exception from the conditional operator, e.g.:

template <typename It>
typename std::iterator_traits<It>::reference
access(It it, It end) {
    return it == end? throw std::runtime_error("no element"): *it;
}

上述函数不能编译, 实例):

The above function doesn't compile, however, when used for example as (live example):

std::vector<int> v;
access(v.begin(), v.end());

编译器抱怨试图绑定一个非 - const 引用临时。编译器不会抱怨 throw - 表达式本身,虽然。所以问题:可以从条件运算符抛出异常,如果是,上面的代码怎么了?

The compiler complains about trying to bind a non-const reference to a temporary. The compiler doesn't complain about the throw-expression per se, though. So the question: Can exceptions be thrown from the conditional operator and, if so, what's going wrong with the above code?

推荐答案

条件运算符在5.16 [expr.cond]中描述。其第2段包括以下文本:

The conditional operator is described in 5.16 [expr.cond]. Its paragraph 2 includes the following text:


第二个或第三个操作数(但不是两个)是一个 throw- / em>(15.1);结果是另一个的类型,并且是prvalue。

The second or the third operand (but not both) is a throw-expression (15.1); the result is of the type of the other and is a prvalue.

这说明允许从条件运算符。然而,即使另一个分支是左值,它变成右值!因此,不可能将左值绑定到条件表达式的结果。除了使用逗号运算符重写条件之外,代码可以被重写以仅从条件运算符的结果获得左值:

That says that it is allowed to throw an exception from the conditional operator. However, even if the other branch is an lvalue, it is turned into an rvalue! Thus, it isn't possible to bind an lvalue to the result of a conditional expression. Aside from rewriting the condition using the comma operator, the code could be rewritten to only obtain the lvalue from the result of the conditional operator:

template <typename It>
typename std::iterator_traits<It>::reference
access(It it, It end) {
    return *(it == end? throw std::runtime_error("no element"): it);
}

有些棘手的事情是返回 const 引用从函数将编译但实际返回一个临时的引用!

The somewhat tricky business is that returning a const reference from the function would compile but actually return a reference to a temporary!

这篇关于三元运算符可以抛出异常吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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