Alright, so I have a poster out on
Constructor Template Argument
Deduction best practices
and one thing you may notice is that
it's the biggest poster in the thing.
And the smallest text of all
the posters in the thing.
So, I want to give you a
little roadmap to the poster
and the key ideas because
even though there is a lot
here this is a really simple
and important feature in C++17.
That we think is going
to have a lot of impact.
So, the elevator pitch is
that in C++14 whenever you
create an argument from a
class template, you have to
give the template parameters.
Like those examples up top.
And it's really, really
painful even if they can be
deduced from the constructor arguments.
So, if I'm creating a lockguard,
I have to know is it a shared mutex,
is it a shared timed
mutex, is it a unique lock,
a shared lock, you name it.
And I don't care, I'm just
creating a critical section
in my code.
And not only don't I care, it's brittle,
my code breaks, if somebody changes that.
So, in C++17 if I want to
create a vector from an
initializer list, it
knows what type it is.
If I want to do a lockguard
from a lock, it's there.
So, this was one of Anthony
Williams' first slides.
That's how you do locking in C++17.
So, since people create objects from
class templates all the time
we think this will be a
high-impact, simple feature.
Unfortunately, no C++ feature
is simple enough that it
does not require best practices.
So before calling it
complete we wanted a set
of best practices.
One other thing I should say.
Let's say I'm trying to create
a vector from two iterators.
The compiler isn't going to know how to do
that from the constructor.
Because it doesn't know you're
supposed to create a vector
of the value types of the iterators.
So we allow you to
specify a deduction rule.
Which is the rule here.
This stuff is all on the poster.
To say, if you're given two
iterators, create a vector
of the iterators value type from that.
So this all works.
So, we have some simple best practices
that everyone should know.
When should you use the feature?
What's use, what's abuse?
Can I get rid of all factory functions?
Well, not so fast.
Some factory functions
do funky stuff, right.
Like, make_tuple, unwraps
reference wrappers.
And using a factory function
can help inform people
that this factory function does
some of it's own processing.
So only use template argument
deduction for constructors
when that's really all your
doing and then not having
the factory function gets
rid of visual noise and
makes it clear to the user
that there's nothing funky
going on.
But if there is use a factory function.
So make_tuple stays.
Another thing that is a
little bit tricky, is when you
call a function template, you
always do it with parentheses.
But when you construct,
there may be braces.
So, the result is we have
to decide what to do then.
So if I construct
brace-initialize a vector
from a vector, am I
constructing a vector of vectors
or I'm copying?
And the answer is: you're copying.
Because you can always explicitly
specify that you want to go
with an initializer list.
And then it will create
a vector from a vector.
But if I'm just copying,
I want the principle of least surprise.
One other thing worth mentioning.
Is, in your classes,
constructors can have
parameter packs in the middle.
But function templates can
only have parameter packs
at the end.
And since we're creating
function templates
from class templates, that
creates an impedance mismatch.
So the thing to do is, in
your classes when you create
constructors, if you have
a parameter pack, put it
at the end.
So, this five minutes...
I'm over? I'm done?
Okay.
So, there is a lot more
stuff on these slides.
I hope this whet your appetite.
And I encourage you
to go and look at the
poster or call me directly.
Thank you very much.
(audience clapping)
