Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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());

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
486 views
Welcome To Ask or Share your Answers For Others

1 Answer

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

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);
}

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...