【发布时间】:2013-12-30 21:49:37
【问题描述】:
有时有一个函数很方便,甚至需要一个语句(返回constexpr时是必要的)。如果需要检查一个条件并且只允许一个语句,则条件运算符是唯一的选择。如果发生错误,最好从条件运算符抛出异常,例如:
template <typename It>
typename std::iterator_traits<It>::reference
access(It it, It end) {
return it == end? throw std::runtime_error("no element"): *it;
}
但是,当用作 (live example) 时,上述函数无法编译:
std::vector<int> v;
access(v.begin(), v.end());
编译器抱怨试图将非const 引用绑定到临时对象。不过,编译器并没有抱怨 throw-expression 本身。那么问题来了:是否可以从条件运算符中抛出异常,如果可以,上面的代码出了什么问题?
【问题讨论】:
-
它通过修改返回类型进行编译:ideone.com/pjOkh8。
-
@stefan:如果你让函数按值返回那么它会copy,它不再是同一个函数了!
-
@DavidRodríguez-dribes 是真的,但它消除了编译错误并表明至少这个编译器不会在异常情况下阻塞三元运算符。
-
请注意,对于 C++14,三元运算符在
constexpr中失去了重要性(从 Clang 3.4 开始完全支持,例如在 coliru.stacked-crooked.com 上)。在constexpr中抛出异常并结合逗号运算符似乎是the idiomatic way to handle errors。