Hello, and welcome to C++ Weekly. I'm your host, Jason Turner. I'm available for code reviews
and on-site training. Now in this episode, I want to talk about decltype(auto), and I will start
by saying that I originally planned to cover much more than I'm actually going to now because
I just really want to tell you like what the point of decltype(auto) is, where it can help,
without going into too many
details. I would like to thank UltraEdit for sponsoring today's episode of C++ Weekly.
UltraEdit is a modern full-featured programmers editor with all the features that we've come to
expect from an editor but considerably less memory overhead than you might be used to
from your current JavaScript based code editor. UltraEdit has been around since 1994, and they
are experts in building tools for programmers. Now besides all of the goodness that we want,
like structured JSON file editing, hex editing, live markdown preview, syntax highlighting
and very large file support, UltraEdit also includes UltraCompare, a powerful diff tool with
binary diffs, structured table diffs, pdf diffs, directory diffs and three-way text file diffs;
and this is only scratching the surface. Be sure to check out this video's description
for links on how to learn more about the full suite of tools that UltraEdit offers. Okay, so
what we need to first mention is just the general idea of decltype(auto) -
it deduces the exact type of an expression. So let's just go ahead and make, well,
code that I hope you would never write.
So you can play a little game here if you want to and test yourself along the way,
and the question is, "What is the type of i?" I'll slowly type in the answer.
So as we can see here with this compile time check, i is an 'int';
and if we go through a few iterations of this...
If I explicitly say I want it to be a 'const int', then I have (get) a 'const int'. Well,
I'm implicitly saying I want a 'const int' by doing 'const auto', so if I put a reference here,
then this is going to be deduced as a reference. Now if I remove this 'const',
then we can see that the type is still 'const int' reference. Now if you haven't
watched my previous episode on how 'auto' works you should go watch that. It has the same rules
as template parameter deduction, so 'auto' is not going to ever deduce a reference; but if I were to
have done decltype(auto), then I'm going to get a 'const int' reference because the
result of the expression of calling get_value is a 'const int' reference. So decltype(auto) deduces
the exact type of an expression. It's really useful in generic code when you need to know,
for whatever reason, the exact type of an expression. Now it can also
be used for something that we could argue as perfect returning, if you will.
Now this doesn't make a whole lot of sense in this not-generic code, so just be aware of that.
So we've now caused a little bit of a problem for ourselves because we are getting a 'auto' return
type deduction here and it's going to follow these normal rules of 'auto' that we expect it to.
So this is no longer a 'const int' reference. It is now just a plain 'int',
but if I were to use decltype(auto)
then I am going to get this perfect forwarding, if you will, of the return type from the wrapped
function; and before you ask, yes, you can use trailing return types here if you are so inclined.
I don't love this particular use of a trailing return type because I kind of want that
visibility that this is decltype(auto) return here. Also if you are curious you can,
in fact, explicitly say that you want the implicitly returned type to be auto deduced
and you can do that. Again, I strongly don't recommend this particular method,
but while we're here let's go ahead and just return the value 1.
In this case we're back to getting an 'int' returned from our function
because we are returning 1, and if I were to
do this, then I'm still getting an 'int' returned.
And again, still an 'int' returned. Now where this can get you in trouble
if you're not paying attention, although the compiler will catch this for you for sure, is this
is still returning an 'int' - see it's an 'int'. It's an 'int', everyone agrees it's an 'int',
however this is an Lvalue. It is a local variable. If I were to do this I basically just turned this
into an expression, and now the return type becomes a 'int' reference and I can prove that
here; but fortunately the compiler is catching us. Fortunately, because I have warnings turned
on and I am treating warnings as errors. So this is easily caught for me. Now if you're not careful
with enabling warnings in your code it will not be caught for you. So, yeah, decltype(auto),
as I already said, deduces the exact type of an expression. Very useful in generic code.
Useful for something that could be described as perfect returning of the exact thing that
was returned from your function, and just for the record I actually teach in my Best Practices class
that you should never treat return as a function call because you might
accidentally create this kind of situation which you would not want to do. So, yeah, thanks for
watching this episode of C++ Weekly. I hope you learned something about
decltype(auto). It is definitely a useful, interesting utility in the case of generic
code. Generally probably not used very much outside of that situation. So be sure to subscribe
and give this video a thumbs up and check out all the links and such in the video description.