And you said something about avoiding complication... (Of
course, in this case the return is just T, so any decltype is
simply added verbosity. I suspect you meant for a and b to
potentially have different types, however, in which case, it
sort of makes sense. If you like implicit type conversions and
unreadable code at the client level---but that too is a long
tradition, dating back to C.)
The question is: how often is something like this relevant?
Perhaps if you're writting a very low level library, but
certainly not in application code.
> But you can write, and since you're pragmatic you will eventually write,
> template< class T >
> auto mul( T a, T b )
> -> decltype( a*b )
> { return a*b; }
(Just to be clear: I think you really mean:
template< typename T1, typename T2 >
auto mul( T1 a, T2 b )
-> decltype( a * b )
{
return a * b;
}
. Otherwise, using decltype is just added verbosity.)
> So, your currently favorite style was good for C, to the degree that a
> syntax that both the C creators and the C++ creator have described as a
> "failed experiment", can be good. It was good in that sense also for
> C++03. With C++11 it's IMHO just ungood, since it no longer covers all
> cases and thus yields an inconsistent mix of declaration styles.
It's good in the same sense that && and ||, rather than "and"
and "or" are good. It's idiomatic for the language. It's what
everyone reading the language expects.
It's also good in the sense that seeing "auto" in front of
a function triggers the reaction: here's some fancy, overly
complicated template mess. Because the ubiquitous use today is
not to use "auto", unless you need it for the decltype.
That doesn't mean that in an abstract, ideal world, something
like:
FUNCTION func( ... ) -> return_type
wouldn't be better. But this isn't an abstract, ideal world;
this is C++. And the keyword "auto" is the same as for
a variable, so it doesn't add any additional information. For
the moment, all of this is new, so best practices haven't really
been established, but generally, from what I can see so far:
"auto" should be limited to variables containing "standardized"
return values of member functions, where the type of the return
value depends on the type of object the member function was
called on. E.g.
auto iter = container.begin();
For just about anything else, it's simply additional
obfuscation.
> d>> Which means that the human eye finds it much easier to just scan through
> >> the code to find a name or note the names, or inspect return types, with
> >> no to read and analyze the text.
> > You're style makes it harder to find the return type. (I never
> > found this a problem in Modula-2, but C++ is not Modula-2.)
> Hm, I can't remember much about Modula-2 declarations.
See above.
> I do remember that good old Niklaus, Praise be Upon Him, for some
> inexplicable reason forced the Modula-2 programmer to use UPPERCASE
> keywords.
Which is as it should be. Upper case stands out; keywords (like
WHILE and IF) should stand out, given the impact they have on
the meaning of the code. Upper case is less readable; the
keywords form a small, closed set, which makes them immediately
identifiable despite this.
The fact that keywords and user symbols were not distinguishable
made early C significantly harder to read. (Today, of course,
syntax highlighting solves this problem, so it's no longer
a bother.)
> Or I think I remember that. Also it was nice with built-in
> coroutine support.
Above all, it had the best model for separate compilation that
I've ever seen. (If I understand correctly, David Vandevorde's
module proposal is based, at least for the semantics, on
Modula-2's modules.)
--
James