Topic: [c++std-core-27231] An implementation of
Author: Herb Sutter <hsutter@microsoft.com>
Date: Fri, 6 Mar 2015 20:53:57 +0000
Raw View
--_000_BLUPR03MB455B567DB1C3C25D676CFF3B81C0BLUPR03MB455namprd_
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
This surprised me so I asked John offline what he meant, and I think we're =
not in disagreement. You can't call those unless there are (also) definitio=
ns.
What I said is correct: If auto (or a concept name) is used in the return t=
ype or parameter type, the definition must be available "in a header." And =
this is already true for auto return types.
I did not mean to imply that you couldn't also have a forward declaration t=
oo (which you can have for function templates but not for auto returns), bu=
t it still must be accompanied by a definition which was the point under di=
scussion, namely that the definition still has to be available in the heade=
r.
Note that I'm excluding the "extern template" case, which is a special case=
and about controlling where instantiations occur (or limiting them) rather=
than about writing the generally usable function template itself... so IMO=
extern templates aren't applicable to this question.
Herb
From: John Spicer [mailto:jhs@edg.com]
Sent: Friday, March 6, 2015 10:38 AM
To: c++std-core@accu.org
Cc: Nicol Bolas; std-discussion@isocpp.org; std-proposals@isocpp.org; faisa=
lv@gmail.com
Subject: [c++std-core-27231] Re: An implementation of enhanced auto deducti=
on and abbreviated template syntax using Clang
On Mar 6, 2015, at 1:27 PM, Herb Sutter <hsutter@microsoft.com<mailto:hsutt=
er@microsoft.com>> wrote:
> To the novice C++ programmer, it isn't "all just programming." Whether so=
mething is a template matters.
Why? Only because of where you put the definition, and that's (a) teachable=
and (b) not new because the same issue exists already with:
auto f() { ... };
This is not a template, but must appear in a header. This is amazingly simi=
lar - and easy to teach as "if the declaration mentions 'auto' or a concept=
name, the compiler needs the definition, either to deduce something or to =
inline the body into the caller." Right?
Actually, that is not right -- in fact, it is mostly wrong.
Only if the return type is deduced do you need a definition.
So:
void f(auto,auto);
void g(ForwardIterator);
do not need definitions.
John.
Herb
PS - Since you mention "novices" writing templates, in my experience (and t=
o my surprise) I've found that not only novices but also intermediate devel=
opers (like 5-7 year veterans) don't write templates very much. [I expect t=
his to change with concepts, for the good.] I discovered this by chance whe=
n I had a class exercise that included writing a very simple template, and =
as I walked through the class during the exercise I was surprised that most=
of the groups asked about the syntax for writing a template - a dead givea=
way that they didn't write templates very often, yet these were pretty expe=
rienced developers who used C++ every day, but just never needed to write t=
emplates much in their normal code. To validate that this wasn't just an ou=
tlier group, I've watched that exercise in a number of classes over several=
years and found a similar result - the majority of even reasonably experie=
nced C++ programmers asked about the syntax for how to write a template.
From: Nicol Bolas [mailto:jmckesson@gmail.com<http://gmail.com>]
Sent: Friday, March 6, 2015 9:21 AM
To: std-discussion@isocpp.org<mailto:std-discussion@isocpp.org>
Cc: c++std-core@accu.org<mailto:c++std-core@accu.org>; std-proposals@isocpp=
..org<mailto:std-proposals@isocpp.org>; faisalv@gmail.com<mailto:faisalv@gma=
il.com>; Herb Sutter
Subject: Re: [c++std-core-27204] Re: An implementation of enhanced auto ded=
uction and abbreviated template syntax using Clang
On Thursday, March 5, 2015 at 7:24:32 PM UTC-5, Herb Sutter wrote:
To paraphrase Stroustrup, it's not about functional programming and object-=
oriented programming and generic programming... "it's all just programming.=
"
> Templates are a fundamentally different kind of construct
Why? Every full specialization of a function template is just a function.
OK, let's explore this.
Let's say that I'm a novice C++ programmer. I don't really know much about =
the language. But I have some basic knowledge.
Now, I've been told that when I write functions, I put a prototype in a hea=
der file so that other people can use it. But I also put the implementation=
in a source file, so that it stays hidden. So I write:
//header
RetType func_name(Type1 arg1, ...);
//source
RetType func_name(Type1 arg1, ...)
{
//implementation
}
OK, fine.
I've also been told about a different class of functions: template function=
s. For reasons I haven't been told and don't much care about (since I'm a n=
ovice), I have to put the implementation in the header file. So I know that=
if I type the word "template", then that function's implementation has to =
go into a header. So I always do this:
//header
template<typename T>
RetType func_name_template(T arg1, ...)
{
//implementation
}
//source doesn't exist.
OK, fine. So... explain to me, the novice C++ programmer, why this doesn't =
work:
//header
RetType func_name_concept(ConceptName arg1, ...);
//source
RetType func_name_concept(ConceptName arg1, ...)
{
//implementation
}
Explain to me, the novice C++ programmer, why this thing which doesn't look=
like a template suddenly became a template. Explain to me why I have to im=
plement it in a header, even though it looks exactly like every other non-t=
emplate function declaration/definition.
To the novice C++ programmer, it isn't "all just programming." Whether some=
thing is a template matters.
Oh, you could say, "well just put everything in a header." That's... insane=
.. Compile times for C++ projects of significant size are already huge even =
when you try to only put what you need in headers. Adding the burden of sho=
ving everything in a header is crazy.
Now, if you can promise me that the same version of C++ that will include t=
his terse syntax will also include modules, I will immediately stop caring.=
Once that exists, then most of the differences between template and non-te=
mplate functions will be erased. And therefore, so too can the syntactic di=
fferences.
But so long as there is a difference in how you implement template and non-=
template functions, I say that there should be an obvious difference in syn=
tax too.
> My issue is with, well, any syntax that declares a template without havin=
g to type either the word "template" or the use of "<>" brackets.
That ship has sailed:
auto plus =3D [](auto x, auto y) { return x+y; }
which even already decays to an ordinary pointer to function, etc.
That doesn't decay into a function pointer. It can't; the operator() is a t=
emplate.
Clarifying Q: Are we mainly arguing about whether to require the three char=
acters =3D, [, and ] ?
Except that there is a difference between creating a lambda (which creates =
a functor) and creating a function (which can be overloaded).
Not only has the ship sailed, but I for one like the direction it's sailing=
.. I see no reason why functions should be forced to spell "template" and "<=
>". What value does it add? It's "just programming." In fact, if we didn't =
have backward compatibility issues with unnamed parameters and such, I'd pe=
rsonally probably be fine with just "auto plus(x,y){x+y}" as an equivalent =
function definition. That still doesn't lose any information.
Gratuitous syntax is often unnecessary and usually harmful. Saying
template<class T, class U>
auto(T x, U y) -> decltype(x+y) { return x+y; }
does not appear to me to contain any more information than
auto plus(auto x, auto y) { return x+y; }
does it?
If you take out the late specified return type (I specifically said that st=
atic deduction was fine), then I don't see the problem with the first one.
Requiring the verbose syntax is gratuitous, if the verbose syntax does not =
add information, does not serve to disambiguate anything, and does not high=
light a dangerous operation or anything else I can see that deserves to hav=
e attention called to it.
There's a disturbing (to me and at least some others) trend in C++ these da=
ys: People seem to be very prone to wanting "more syntax" lately. It's rath=
er Vasa-like, if only lexically. Let me channel certain influential committ=
ee members and say: 'People these days are always asking for more syntax! T=
here's no proposal they've seen that they couldn't make uglier with more sy=
ntax!'
Important note: The point here is NOT terseness for terseness' sake. I am n=
ot arguing that terser is somehow better, that terseness is virtuous in its=
elf. Too many people glorify languages because they're terser; fewer charac=
ters alone doesn't make code clearer. Rather, my point is to avoid gratuito=
us verbosity. At the other end of the pendulum, too many people glorify ver=
bose syntax because they think _that_ is somehow inherently clearer; usuall=
y it isn't. So I am arguing that neither is verbosity virtuous in itself.
Herb
The virtue to me of the large syntax of templates is this:
Templates have to be treated differently from non-templates. They have diff=
erent needs of where their implementations live. And because of those needs=
, templates make your code compile slower. Even ignoring the compile-time c=
ost of template instantiation, your source has to go in the header. And if =
that header is included in more than one place, then the source for that te=
mplate must be recompiled for every place it is included.
Therefore, the bulky template syntax pokes you in the eye every time you wr=
ite something that's going to compile slower. It immediately lets you know =
that this function operates under fundamentally different rules than regula=
r functions.
Again, if you could guarantee that we get modules alongside this syntax, I'=
d be fine, since using templates will not hurt your compile times nearly as=
much.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--_000_BLUPR03MB455B567DB1C3C25D676CFF3B81C0BLUPR03MB455namprd_
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html xmlns:v=3D"urn:schemas-microsoft-com:vml" xmlns:o=3D"urn:schemas-micr=
osoft-com:office:office" xmlns:w=3D"urn:schemas-microsoft-com:office:word" =
xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml" xmlns=3D"http:=
//www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dus-ascii"=
>
<meta name=3D"Generator" content=3D"Microsoft Word 15 (filtered medium)">
<base href=3D"x-msg://936/"><style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:"Times New Roman",serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
span.apple-converted-space
{mso-style-name:apple-converted-space;}
span.apple-tab-span
{mso-style-name:apple-tab-span;}
span.styled-by-prettify
{mso-style-name:styled-by-prettify;}
span.EmailStyle20
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:#1F497D;}
..MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext=3D"edit" spidmax=3D"1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext=3D"edit">
<o:idmap v:ext=3D"edit" data=3D"1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang=3D"EN-US" link=3D"blue" vlink=3D"purple">
<div class=3D"WordSection1">
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">This surprised me so I asked John off=
line what he meant, and I think we’re not in disagreement. You can=
217;t call those unless there are (also) definitions.<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">What I said is correct: If auto (or a=
concept name) is used in the return type or parameter type, the definition=
must be available “in a header.” And this is
already true for auto return types.<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">I did not mean to imply that you coul=
dn’t also have a forward declaration too (which you can have for func=
tion templates but not for auto returns), but it still
must be accompanied by a definition which was the point under discussion, =
namely that the definition still has to be available in the header.<o:p></o=
:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">Note that I’m excluding the =
220;extern template” case, which is a special case and about controll=
ing where instantiations occur (or limiting them) rather than about
writing the generally usable function template itself… so IMO extern=
templates aren’t applicable to this question.<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">Herb<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
<div style=3D"border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in =
4.0pt">
<div>
<div style=3D"border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in =
0in 0in">
<p class=3D"MsoNormal"><b><span style=3D"font-size:11.0pt;font-family:"=
;Calibri",sans-serif">From:</span></b><span style=3D"font-size:11.0pt;=
font-family:"Calibri",sans-serif"> John Spicer [mailto:jhs@edg.co=
m]
<br>
<b>Sent:</b> Friday, March 6, 2015 10:38 AM<br>
<b>To:</b> c++std-core@accu.org<br>
<b>Cc:</b> Nicol Bolas; std-discussion@isocpp.org; std-proposals@isocpp.org=
; faisalv@gmail.com<br>
<b>Subject:</b> [c++std-core-27231] Re: An implementation of enhanc=
ed auto deduction and abbreviated template syntax using Clang<o:p></o:p></s=
pan></p>
</div>
</div>
<p class=3D"MsoNormal"><o:p> </o:p></p>
<p class=3D"MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class=3D"MsoNormal">On Mar 6, 2015, at 1:27 PM, Herb Sutter <<a href=
=3D"mailto:hsutter@microsoft.com">hsutter@microsoft.com</a>> wrote:<o:p>=
</o:p></p>
</div>
<p class=3D"MsoNormal"><br>
<br>
<o:p></o:p></p>
<blockquote style=3D"margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">></span><span class=3D"apple-conve=
rted-space"> </span>To the novice C++ programmer, it<span clas=
s=3D"apple-converted-space"> </span><i>isn't</i><span class=3D"apple-c=
onverted-space"> </span>"all
just programming." Whether something is a template<span class=3D"appl=
e-converted-space"> </span><i>matters</i>.<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">Why? Only because of where you put th=
e definition, and that’s (a) teachable and (b) not new because the sa=
me issue exists already with:</span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> &=
nbsp; auto f() { … };=
</span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">This is not a template, but must appe=
ar in a header. This is amazingly similar – and easy to teach as R=
20;if the declaration mentions ‘auto’ or a concept name, the
compiler needs the definition, either to deduce something or to inline the=
body into the caller.” Right?</span><o:p></o:p></p>
</div>
</div>
</blockquote>
<div>
<p class=3D"MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class=3D"MsoNormal">Actually, that is not right -- in fact, it is mostly=
wrong.<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class=3D"MsoNormal">Only if the return type is deduced do you need a def=
inition.<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class=3D"MsoNormal">So:<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span class=3D"apple-tab-span"> &nb=
sp; </span>void f(auto,auto);<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span class=3D"apple-tab-span"> &nb=
sp; </span>void g(ForwardIterator);<o:p></o:p=
></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class=3D"MsoNormal">do not need definitions.<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class=3D"MsoNormal">John.<o:p></o:p></p>
</div>
<p class=3D"MsoNormal"><br>
<br>
<o:p></o:p></p>
<blockquote style=3D"margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">Herb</span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">PS – Since you mention “n=
ovices” writing templates, in my experience (and to my surprise) I=
217;ve found that not only novices but also intermediate developers (like
5-7 year veterans) don’t write templates very much. [I expect this t=
o change with concepts, for the good.] I discovered this by chance when I h=
ad a class exercise that included writing a very simple template, and as I =
walked through the class during the exercise
I was surprised that most of the groups asked about the syntax for writing=
a template – a dead giveaway that they didn’t write templates =
very often, yet these were pretty experienced developers who used C+=
3; every day, but just never needed to write templates
much in their normal code. To validate that this wasn’t just an outl=
ier group, I’ve watched that exercise in a number of classes over sev=
eral years and found a similar result – the majority of even reasonab=
ly experienced C++ programmers asked about the syntax
for how to write a template.</span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div style=3D"border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in =
4.0pt">
<div>
<div style=3D"border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in =
0in 0in">
<div>
<p class=3D"MsoNormal"><b><span style=3D"font-size:11.0pt;font-family:"=
;Calibri",sans-serif">From:</span></b><span class=3D"apple-converted-s=
pace"><span style=3D"font-size:11.0pt;font-family:"Calibri",sans-=
serif"> </span></span><span style=3D"font-size:11.0pt;font-family:&quo=
t;Calibri",sans-serif">Nicol
Bolas [mailto:jmckesson@<a href=3D"http://gmail.com"><span style=3D"color:=
#954F72">gmail.com</span></a>]<span class=3D"apple-converted-space"> <=
/span><br>
<b>Sent:</b><span class=3D"apple-converted-space"> </span>Friday, Marc=
h 6, 2015 9:21 AM<br>
<b>To:</b><span class=3D"apple-converted-space"> </span><a href=3D"mai=
lto:std-discussion@isocpp.org"><span style=3D"color:#954F72">std-discussion=
@isocpp.org</span></a><br>
<b>Cc:</b><span class=3D"apple-converted-space"> </span><a href=3D"mai=
lto:c++std-core@accu.org"><span style=3D"color:#954F72">c++=
std-core@accu.org</span></a>;<span class=3D"apple-converted-space"> </=
span><a href=3D"mailto:std-proposals@isocpp.org"><span style=3D"color:#954F=
72">std-proposals@isocpp.org</span></a>;<span class=3D"apple-converted-spac=
e"> </span><a href=3D"mailto:faisalv@gmail.com"><span style=3D"color:#=
954F72">faisalv@gmail.com</span></a>;
Herb Sutter<br>
<b>Subject:</b><span class=3D"apple-converted-space"> </span>Re: [c=
3;+std-core-27204] Re: An implementation of enhanced auto deduction and=
abbreviated template syntax using Clang</span><o:p></o:p></p>
</div>
</div>
</div>
<div>
<p class=3D"MsoNormal"> <o:p></o:p></p>
</div>
<div>
<div>
<p class=3D"MsoNormal">On Thursday, March 5, 2015 at 7:24:32 PM UTC-5, Herb=
Sutter wrote:<o:p></o:p></p>
</div>
<blockquote style=3D"border:none;border-left:solid #CCCCCC 1.0pt;padding:0i=
n 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-=
bottom:5.0pt">
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">To paraphrase Stroustrup, it’s =
not about functional programming and object-oriented programming and generi=
c programming… “it’s all<span class=3D"apple-converted-sp=
ace"> </span><i>just
programming</i>.”</span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">><span class=3D"apple-converted-sp=
ace"> </span></span>Templates are a fundamentally different kind of co=
nstruct<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">Why? Every full specialization of a f=
unction template is just a function.</span><o:p></o:p></p>
</div>
</blockquote>
<div>
<p class=3D"MsoNormal" style=3D"margin-bottom:12.0pt"><br>
OK, let's explore this.<br>
<br>
Let's say that I'm a novice C++ programmer. I don't really know muc=
h about the language. But I have some basic knowledge.<br>
<br>
Now, I've been told that when I write functions, I put a prototype in a hea=
der file so that other people can use it. But I also put the implementation=
in a source file, so that it stays hidden. So I write:<o:p></o:p></p>
<div style=3D"border:solid #BBBBBB 1.0pt;padding:0in 0in 0in 0in;word-wrap:=
break-word">
<div>
<p class=3D"MsoNormal" style=3D"background:#FAFAFA"><span class=3D"styled-b=
y-prettify"><span style=3D"font-size:10.0pt;font-family:"Courier New&q=
uot;;color:#880000">//header</span></span><span style=3D"font-size:10.0pt;f=
ont-family:"Courier New""><br>
<span class=3D"styled-by-prettify"><span style=3D"color:#660066">RetType</s=
pan></span><span class=3D"apple-converted-space"> </span><span class=
=3D"styled-by-prettify">func_name<span style=3D"color:#666600">(</span><spa=
n style=3D"color:#660066">Type1</span></span><span class=3D"apple-converted=
-space"> </span><span class=3D"styled-by-prettify">arg1<span style=3D"=
color:#666600">,</span> <span style=3D"color:#666600">...);</span></sp=
an><br>
<br>
<span class=3D"styled-by-prettify"><span style=3D"color:#880000">//source</=
span></span><br>
<span class=3D"styled-by-prettify"><span style=3D"color:#660066">RetType</s=
pan></span><span class=3D"apple-converted-space"> </span><span class=
=3D"styled-by-prettify">func_name<span style=3D"color:#666600">(</span><spa=
n style=3D"color:#660066">Type1</span></span><span class=3D"apple-converted=
-space"> </span><span class=3D"styled-by-prettify">arg1<span style=3D"=
color:#666600">,</span> <span style=3D"color:#666600">...)</span></spa=
n><br>
<span class=3D"styled-by-prettify"><span style=3D"color:#666600">{</span></=
span><br>
<span class=3D"styled-by-prettify"><span style=3D"color:#880000">//implemen=
tation</span></span><br>
<span class=3D"styled-by-prettify"><span style=3D"color:#666600">}</span></=
span></span><o:p></o:p></p>
</div>
</div>
<p class=3D"MsoNormal" style=3D"margin-bottom:12.0pt"><br>
<br>
OK, fine.<br>
<br>
I've also been told about a different class of functions: template function=
s. For reasons I haven't been told and don't much care about (since I'm a n=
ovice), I have to put the implementation in the header file. So I know that=
if I type the word "template",
then that function's implementation has to go into a header. So I always d=
o this:<o:p></o:p></p>
<div style=3D"border:solid #BBBBBB 1.0pt;padding:0in 0in 0in 0in;word-wrap:=
break-word">
<div>
<p class=3D"MsoNormal" style=3D"background:#FAFAFA"><span class=3D"styled-b=
y-prettify"><span style=3D"font-size:10.0pt;font-family:"Courier New&q=
uot;;color:#880000">//header</span></span><span style=3D"font-size:10.0pt;f=
ont-family:"Courier New""><br>
<span class=3D"styled-by-prettify"><span style=3D"color:#000088">template</=
span><span style=3D"color:#666600"><</span><span style=3D"color:#000088"=
>typename</span></span><span class=3D"apple-converted-space"> </span><=
span class=3D"styled-by-prettify">T<span style=3D"color:#666600">></span=
></span><br>
<span class=3D"styled-by-prettify"><span style=3D"color:#660066">RetType</s=
pan></span><span class=3D"apple-converted-space"> </span><span class=
=3D"styled-by-prettify">func_name_template<span style=3D"color:#666600">(</=
span>T arg1<span style=3D"color:#666600">,</span> <span style=3D"color=
:#666600">...)</span></span><br>
<span class=3D"styled-by-prettify"><span style=3D"color:#666600">{</span></=
span><br>
<span class=3D"styled-by-prettify"><span style=3D"color:#880000">//implemen=
tation</span></span><br>
<span class=3D"styled-by-prettify"><span style=3D"color:#666600">}</span></=
span><br>
<br>
<span class=3D"styled-by-prettify"><span style=3D"color:#880000">//source d=
oesn't exist.</span></span></span><o:p></o:p></p>
</div>
</div>
<p class=3D"MsoNormal" style=3D"margin-bottom:12.0pt"><br>
<br>
OK, fine. So... explain to me, the novice C++ programmer, why this =
doesn't work:<o:p></o:p></p>
<div style=3D"border:solid #BBBBBB 1.0pt;padding:0in 0in 0in 0in;word-wrap:=
break-word">
<div>
<p class=3D"MsoNormal" style=3D"background:#FAFAFA"><span class=3D"styled-b=
y-prettify"><span style=3D"font-size:10.0pt;font-family:"Courier New&q=
uot;;color:#880000">//header</span></span><span style=3D"font-size:10.0pt;f=
ont-family:"Courier New""><br>
<span class=3D"styled-by-prettify"><span style=3D"color:#660066">RetType</s=
pan></span><span class=3D"apple-converted-space"> </span><span class=
=3D"styled-by-prettify">func_name_concept<span style=3D"color:#666600">(</s=
pan><span style=3D"color:#660066">ConceptName</span></span><span class=3D"a=
pple-converted-space"> </span><span class=3D"styled-by-prettify">arg1<=
span style=3D"color:#666600">,</span> <span style=3D"color:#666600">..=
..);</span></span><br>
<br>
<span class=3D"styled-by-prettify"><span style=3D"color:#880000">//source</=
span></span><br>
<span class=3D"styled-by-prettify"><span style=3D"color:#660066">RetType</s=
pan></span><span class=3D"apple-converted-space"> </span><span class=
=3D"styled-by-prettify">func_name_concept<span style=3D"color:#666600">(</s=
pan><span style=3D"color:#660066">ConceptName</span></span><span class=3D"a=
pple-converted-space"> </span><span class=3D"styled-by-prettify">arg1<=
span style=3D"color:#666600">,</span> <span style=3D"color:#666600">..=
..)</span></span><br>
<span class=3D"styled-by-prettify"><span style=3D"color:#666600">{</span></=
span><br>
<span class=3D"styled-by-prettify"><span style=3D"color:#880000">//implemen=
tation</span></span><br>
<span class=3D"styled-by-prettify"><span style=3D"color:#666600">}</span></=
span></span><o:p></o:p></p>
</div>
</div>
<p class=3D"MsoNormal" style=3D"margin-bottom:12.0pt"><br>
Explain to me, the novice C++ programmer, why this thing which does=
n't look like a template suddenly<span class=3D"apple-converted-space">&nbs=
p;</span><i>became</i><span class=3D"apple-converted-space"> </span>a =
template. Explain to me why I have to implement it in
a header, even though it looks exactly like every other non-template funct=
ion declaration/definition.<br>
<br>
To the novice C++ programmer, it<span class=3D"apple-converted-spac=
e"> </span><i>isn't</i><span class=3D"apple-converted-space"> </s=
pan>"all just programming." Whether something is a template<span =
class=3D"apple-converted-space"> </span><i>matters</i>.<br>
<br>
Oh, you could say, "well just put<span class=3D"apple-converted-space"=
> </span><i>everything</i><span class=3D"apple-converted-space"> =
</span>in a header." That's... insane. Compile times for C++ p=
rojects of significant size are already huge even when you try to
only put what you need in headers. Adding the burden of shoving everything=
in a header is crazy.<br>
<br>
Now, if you can promise me that the same version of C++ that will i=
nclude this terse syntax will also include<span class=3D"apple-converted-sp=
ace"> </span><i>modules</i>, I will immediately stop caring. Once that=
exists, then most of the differences between template
and non-template functions will be erased. And therefore, so too can the s=
yntactic differences.<br>
<br>
But so long as there is a difference in how you implement template and non-=
template functions, I say that there should be an obvious difference in syn=
tax too.<o:p></o:p></p>
</div>
<blockquote style=3D"border:none;border-left:solid #CCCCCC 1.0pt;padding:0i=
n 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-=
bottom:5.0pt">
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">><span class=3D"apple-converted-sp=
ace"> </span></span>My issue is with, well, any syntax that declares a=
template without having to type either the word "template"
or the use of "<>" brackets.<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">That ship has sailed:</span><o:p></o:=
p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> &=
nbsp; auto plus =3D [](auto=
x, auto y) { return x+y; }</span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">which even already decays to an ordin=
ary pointer to function, etc.</span><o:p></o:p></p>
</div>
</blockquote>
<div>
<div>
<p class=3D"MsoNormal"><br>
That doesn't decay into a function pointer. It can't; the operator() is a t=
emplate.<br>
<o:p></o:p></p>
</div>
</div>
<blockquote style=3D"border:none;border-left:solid #CCCCCC 1.0pt;padding:0i=
n 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-=
bottom:5.0pt">
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">Clarifying Q: Are we mainly arguing a=
bout whether to require the three characters =3D, [, and ] ?</span><o:p></o=
:p></p>
</div>
</blockquote>
<div>
<p class=3D"MsoNormal" style=3D"margin-bottom:12.0pt">Except that there is =
a difference between creating a lambda (which creates a functor) and creati=
ng a function (which can be overloaded).<o:p></o:p></p>
</div>
<blockquote style=3D"border:none;border-left:solid #CCCCCC 1.0pt;padding:0i=
n 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-=
bottom:5.0pt">
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">Not only has the ship sailed, but I f=
or one like the direction it’s sailing. I see no reason why functions=
should be forced to spell “template” and “<>”=
;. What
value does it add? It’s “just programming.” In fact, if =
we didn’t have backward compatibility issues with unnamed parameters =
and such, I’d personally probably be fine with just “auto plus(=
x,y){x+y}” as an equivalent function definition. That still doesn=
’t
lose any information.</span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">Gratuitous syntax is often unnecessar=
y and usually harmful. Saying</span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> &=
nbsp; template<class T, =
class U></span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> &=
nbsp; auto(T x, U y) -> =
decltype(x+y) { return x+y; }</span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">does not appear to me to contain any =
more information than</span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> &=
nbsp; auto plus(auto x, aut=
o y) { return x+y; }</span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">does it?</span><o:p></o:p></p>
</div>
</blockquote>
<div>
<div>
<p class=3D"MsoNormal">If you take out the late specified return type (I sp=
ecifically said that static deduction was fine), then I don't see the probl=
em with the first one.<br>
<br>
<o:p></o:p></p>
</div>
</div>
<blockquote style=3D"border:none;border-left:solid #CCCCCC 1.0pt;padding:0i=
n 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-=
bottom:5.0pt">
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">Requiring the verbose syntax is gratu=
itous, if the verbose syntax does not add information, does not serve to di=
sambiguate anything, and does not highlight a
dangerous operation or anything else I can see that deserves to have atten=
tion called to it.</span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">There’s a disturbing (to me and=
at least some others) trend in C++ these days: People seem to be v=
ery prone to wanting “more syntax” lately. It’s rather Va=
sa-like,
if only lexically. Let me channel certain influential committee members an=
d say: ‘People these days are always asking for more syntax! There=
217;s no proposal they’ve seen that they couldn’t make uglier w=
ith more syntax!’</span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">Important note: The point here is NOT=
terseness for terseness’ sake. I am not arguing that terser is someh=
ow better, that terseness is virtuous in itself. Too
many people glorify languages because they’re terser; fewer characte=
rs alone doesn’t make code clearer. Rather, my point is to avoid grat=
uitous verbosity. At the other end of the pendulum, too many people glorify=
verbose syntax because they think _that_ is
somehow inherently clearer; usually it isn’t. So I am arguing that n=
either is verbosity virtuous in itself.</span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Ca=
libri",sans-serif;color:#1F497D">Herb</span><o:p></o:p></p>
</div>
</blockquote>
<div>
<div>
<p class=3D"MsoNormal">The virtue to me of the large syntax of templates is=
this:<br>
<br>
Templates have to be treated differently from non-templates. They have diff=
erent needs of where their implementations live. And because of those needs=
, templates make your code compile slower. Even ignoring the compile-time c=
ost of template instantiation, your
source has to go in the header. And if that header is included in more tha=
n one place, then the source for that template must be recompiled for every=
place it is included.<br>
<br>
Therefore, the bulky template syntax pokes you in the eye every time you wr=
ite something that's going to compile slower. It immediately lets you know =
that this function operates under fundamentally different rules than regula=
r functions.<br>
<br>
Again, if you could guarantee that we get modules alongside this syntax, I'=
d be fine, since using templates will not hurt your compile times nearly as=
much.<o:p></o:p></p>
</div>
</div>
<div>
<p class=3D"MsoNormal"> <o:p></o:p></p>
</div>
</div>
</div>
</div>
</blockquote>
</div>
<p class=3D"MsoNormal"><o:p> </o:p></p>
</div>
</div>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--_000_BLUPR03MB455B567DB1C3C25D676CFF3B81C0BLUPR03MB455namprd_--
.