what is the difference between returning auto vrs returning decltype(auto)?

when should we choose to return decltype(auto) instead of returning auto?


For instance:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
	template<typename CB>
	class CountCalls
	{
		CB callback;
		long calls = 0;
	public:
		CountCalls(CB cb) : callback(cb) {}
		template<typename ...Args>
		decltype(auto) operator()(Args&& ...args)
		{
			++calls;
			return callback(std::forward<Args>(args)...);
		}
		long count() const
		{
			return calls;
		}
	};


Why do we use here decltype(auto)??


Thanks,
Juan
Simply, you're doing perfect forwarding (ie value, ref, ref-ref etc are forwarded as is). Auto doesn't maintain ref etc. decltype(auto) does.

See
https://en.cppreference.com/w/cpp/language/decltype
and 2).

As you don't know the type then auto is used.
then why use auto?
why not use decltype(auto) all the time?
Last edited on
You need to be careful returning references from functions. If you return a reference to a local variable or a temporary then you're in trouble.

It's not always obvious whether an expression returns a reference or not but if you use decltype(auto) then it is important.

Can you spot the problem with the following code?

1
2
3
4
5
template <typename T>
decltype(auto) clampZero(T val)
{
	return std::max(0, val);
}

Spoiler: std::max returns a reference to one of its arguments and since you use decltype(auto) it means that clampZero will return either a reference to the parameter val or to the temporary 0. In either case this is a problem because neither of them will be alive after the function has ended.

Using auto instead of decltype(auto) to deduce the return type is safer (because it avoids references) and it's more easily understood because you can clearly see that it doesn't return a reference (unless you explicitly use & or && after). I therefore think it's best to prefer auto and only use decltype(auto) when necessary.
Last edited on
Sorry helios but I never quite understood it.... I apologize.
Thanks Peter87 very clear!!

I finally got it - your sample was right on target!
Topic archived. No new replies allowed.