简体   繁体   中英

SFINAE: 'static_cast<void>()' or ', void()'?

When performing SFINAE on an arbitrary type, it's often necessary to cast the result of an expression to void . I've seen two ways of doing this; a cast to void:

(void)(expr)    // or static_cast<void>(expr)

Or, alternatively, using the comma operator with a void prvalue RHS:

(expr), void()

It's my understanding that in both cases expr is evaluated (for well-formedness, in a non-evaluated context) and the result (or result type, in a non-evaluated context) discarded; it is not possible in either case for even a pathological class T to override T::operator void() or operator,(T, void) . (See: Why is "operator void" not invoked with cast syntax? , What does the 'void()' in 'auto f(params) -> decltype(..., void())' do? ).

That said, are these two idioms equivalent, or are there any circumstances under which one should be preferred to the other (possibly with nonstandard compilers)? If not, are there any reasons (eg understandability) to prefer one over the other?

They both meet the requirements needed:

  • Require that expr be valid as a discarded-value expression, and only that.
  • Always have type void (for use in trailing return types or for partial specializations )

Thus the methods are equivalent when considering the above criteria. Keeping that in mind, I'd recommend to use whatever is more concise in your code; but whatever you choose, stick to it for consistency.
One can also use a functional style cast, since it is by definition equivalent to the explicit cast notation when there is only one argument - ie

auto g(auto f) -> decltype(void( f(1, 2, 3) ));

also works.

The difference is basically stylistic.

In some cases, due to the low precedence of the comma operator, the void() form can avoid an extra pair of parentheses. For instance, foo + bar, void() works just fine, but (void) (foo + bar) (or the functional-style cast equivalent) will require parenthesizing the whole expression.

In other cases, using a (void) cast may be more concise. For example, to protect against overloaded commas in ++it1, ++it2, ++it3 , you can use one (void) cast - ++it1, (void) ++it2, ++it3 , but to use void() would require writing it twice: ++it1, void(), ++it2, void(), ++it3 .

强制转换为空,因为逗号可以重载。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM