Can somebody explain how does std::declval work? I've found this implementation inside gcc headers/type_traits (lines 2248-2262), which is (cleared up a bit to improve readability):
template<typename _Tp>
struct __declval_protector
{
static const bool __stop = false;
static typename add_rvalue_reference<_Tp>::type __delegate();
};
template<typename _Tp>
typename add_rvalue_reference<_Tp>::type
declval ()
{
static_assert(__declval_protector<_Tp>::__stop, "declval() must not be used!");
return __declval_protector<_Tp>::__delegate();
}
I don't understand the part return __declval_protector<_Tp>::__delegate()
, does it call the default initializer for an Rvalue reference of type T?
Also i don't understand why the static_assert
is not called every time I call declval
, since __stop
is always false (And how can it distinguish between unevaluated contexts and evaluated ones?).
EDIT: From what I understand now, all this stuff is equivalent to:
template<typenam _Tp>
struct __declval_protector
{
const bool __stop = false;
};
template<typename _Tp>
typename add_rvalue_reference<_Tp>::type
mydeclval ()
{
static_assert(__declval_protector<_Tp>::__stop, "declval() must not be used!");
}
But of course the compiler will issue that we do not return anything.
I don't understand why the static_assert is not called every time I call declval, since __stop is always false
Your premise is wrong. The static assert is indeed called every time you call declval
. The trick is that you must never call declval
. It must only be used in unevaluated contexts. That's why the static assertion is there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With