user9196120
user9196120

Reputation: 401

std::declval and unevaluated expressions

With reference to the following example in Proposing Standard Library Support for the C++ Detection Idiom:

// primary template handles types that do not support pre-increment
template< class, class = void_t<> >
struct
has_pre_increment_member : false_type { };

// specialization recognizes types that do support pre-increment
template< class T >
struct
has_pre_increment_member<T, void_t<decltype( ++declval<T&>() )>> : true_type { };

how does the expression ++declval<T&>() classify as unevaluated?

In the above, assuming declval() returns T& as discussed in Is there a reason declval returns add_rvalue_reference instead of add_lvalue_reference , doesn't the result of the expression ++T& (resulting from ++declval<T&>) become odr-used as opposed to unevaluated? As per ODR-use:

a reference is odr-used if it is used and its referent is not known at compile time;

In the above case, isn't the referent not known at compile time? In that case, how can the reference be used with declval() in the first place?

Upvotes: 1

Views: 169

Answers (1)

Barry
Barry

Reputation: 303127

how does the expression ++declval<T&>() classify as unevaluated?

Because it's within decltype():

The operand of the decltype specifier is an unevaluated operand.

A function, variable, structured binding, assignment operator or constructor, etc. must appear in a potentially evaluated expression in order to be odr-used. decltype() doesn't meet that criteria.

Upvotes: 3

Related Questions