J
James Kanze
On 09.11.2013 22:14, Ian Collins wrote:
Alf P. Steinbach wrote:
This code is in support of some API functionality:
Code:inline auto can_inflate( gdi::Rect const& r, int const dx, int const dy ) -> bool Why do you insist on using this form rather than the sorter, more conventional form? Uhm, the word "insist" incorrectly indicates some kind of opposition to the adoption of `auto`. ;-) Anyway, there are many good reasons, but for me the most important is a consistent visual layout: * function name at fixed place. * return type visually separated.[/QUOTE] You mean like the way I've always written function definitions: bool can_inflate( ... ) { } The function name is always at the start of the line. Has been since I learned C. (Back then, about all we had for searching was grep, and "grep ^can_inflate" would always get the definition, and nothing else.)[/QUOTE][/QUOTE] [QUOTE] No, with C++11 that style can no longer (in practice) yield a consistent layout, since in cases where the return type depends on the argument types one avoids a lot of complication and verbosity by using `auto`. For details of how bad it can be see Andrei's "min max revisited" article in DDJ (I leave it to the reader to google it). For example, even in C++11 you can NOT simply write[/QUOTE] [QUOTE] template< class T > decltype( a*b ) mul( T a, T b ) { return a*b; }[/QUOTE] 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. [QUOTE] But you can write, and since you're pragmatic you will eventually write,[/QUOTE] [QUOTE] template< class T > auto mul( T a, T b ) -> decltype( a*b ) { return a*b; }[/QUOTE] (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.) [QUOTE] 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.[/QUOTE] 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. [QUOTE] d>> Which means that the human eye finds it much easier to just scan through[/QUOTE] [QUOTE] Hm, I can't remember much about Modula-2 declarations.[/QUOTE] See above. [QUOTE] I do remember that good old Niklaus, Praise be Upon Him, for some inexplicable reason forced the Modula-2 programmer to use UPPERCASE keywords.[/QUOTE] 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.) [QUOTE] Or I think I remember that. Also it was nice with built-in coroutine support.[/QUOTE] 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.)