Reputation: 401
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
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