Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does std::declval return a value?

Tags:

c++

I wanted to try writing a template wrapper that checks whether a class has a member function. and for this it was necessary to use std::declval

template<typename T>
struct has_member<T, void_t<decltype(std::declval<T>().push_back())>>:std::true_type{};

As I saw, the implementation of declval should be like this:

template<typename T>
T&& declval() noexcept;

And actually, it may be a odd question ,but why does declval have no return statement ?

If I understand correctly, it should return rvalue to the place of its call:

template<typename T>
struct has_member<T, void_t<decltype(T&&.push_back())>>:std::true_type{};

But we don't use return in the implementation . Maybe it's because we don't have a function body?I would like to understand why this is possible. I would be happy to help

like image 299
Omegon Avatar asked Jan 26 '26 22:01

Omegon


1 Answers

declval has no return statement because the function has no implementation. If you ever tried to call declval, you would get a compile error.

declval exists to be used in what C++ calls an "unevaluated context". This is in a place where an expression will be parsed, the types used worked out, but the expression will never actually be evaluated. The expression given to decltype is an unevaluated context.

Even though declval has no implementation, it is a function with a well-defined return type. So even though you can't actually execute it, the compiler does know what the type of declval<T>() will be. And therefore, the compiler can examine the expression containing it.

See, T&& is a type; you cannot use . on a type. The result of calling a function is an object (or void), which has a type, but isn't itself a type. What you want to say is "assuming I have a value of type T, I want to do X to it". You can't say that with T&& because it's a type, not an object. And you don't want to limit T to things which are default constructible, so you can't just say T{}.

That's where declval comes in.

like image 156
Nicol Bolas Avatar answered Jan 28 '26 13:01

Nicol Bolas