Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enlightening Usage of C++11 decltype

I've just seen this really nice talk Rock Hard: C++ Evolving by Boris Jabes. In the section of the talk concerning Higher-Order Generic Programming he says that the following is an example of a function that is more generic with regards to its return type and leads to fewer template function overloads

template <typename Func>
auto deduce(const Func & f) -> decltype(f())
{..}

This however can be realized using plain template syntax as follows

template <typename Func>
Func deduce(const Func & f)
{..}

so I guess the example chosen doesn't really show the unique power of decltype. Can anyone give an example of such a more enlightening usage of decltype?

like image 571
Nordlöw Avatar asked Oct 01 '11 23:10

Nordlöw


2 Answers

Your suspicions are incorrect.

void f() { }

Now deduce(&f) has type void, but with your rewrite, it has type void(*)(). In any case, everywhere you want to get the type of an expression or declaration, you use decltype (note the subtle difference in between these two. decltype(x) is not necessarily the same as decltype((x))).

For example, it's likely your Standard library implementation somewhere contains lines like

using size_t = decltype(sizeof(0));
using ptrdiff_t = decltype((int*)0 - (int*)0);
using nullptr_t = decltype(nullptr);

Finding out the correct return type of add has been a challenging problem throughout past C++. This is now an easy exercise.

template<typename A, typename B> 
auto add(A const& a, B const& b) -> decltype(a + b) { return a + b; }

Little known is that you can use decltype before :: and in a pseudo destructor name

// has no effect
(0).~decltype(0)();

// it and ite will be iterators into an initializer list 
auto x = { 1, 2, 3 };
decltype(x)::iterator it = x.begin(), ite = x.end();
like image 184
Johannes Schaub - litb Avatar answered Oct 27 '22 02:10

Johannes Schaub - litb


std::for_each(c.begin(), c.end(), [](decltype (c.front()) val){val*=2;});

Autodeducting the value_type of the container c can't be done without decltype.

like image 43
Viktor Sehr Avatar answered Oct 27 '22 01:10

Viktor Sehr