问题描述
有时方便,甚至有必要有一个只有一个语句的函数(当返回 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:
这说明允许从条件运算符。然而,即使另一个分支是左值,它变成右值!因此,不可能将左值绑定到条件表达式的结果。除了使用逗号运算符重写条件之外,代码可以被重写以仅从条件运算符的结果获得左值:
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!
这篇关于三元运算符可以抛出异常吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!