Mattia F.
Mattia F.

Reputation: 1740

How does std::declval work?

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.

Upvotes: 5

Views: 1652

Answers (1)

Kerrek SB
Kerrek SB

Reputation: 477040

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.

Upvotes: 18

Related Questions