[Development] RFC: more liberal 'auto' rules?

Bubke Marco Marco.Bubke at theqtcompany.com
Sat Dec 5 13:08:44 CET 2015


On December 5, 2015 12:08:51 Julien Blanc <julien.blanc at nmc-company.com> wrote:

> Le vendredi 04 décembre 2015 à 18:10 -0500, Matthew Woehlke a écrit : 
>> On 2015-12-04 17:43, André Pönitz wrote:
>> > On Fri, Dec 04, 2015 at 04:33:26PM -0500, Matthew Woehlke wrote:
>> >> Which of these is easier to read? (More importantly, which is easier to
>> >> *verify* that it is correct?)
>> >>
>> >>   for (int i = 0; i < list.size(); ++i)
>> >>     foo(list[i]);
> [snip] 
>> 
>> >>   for (auto i : qtIndexRange(list.size())
>> >>     foo(list[i]);
>> > 
>> > In any case, this is an uncommon pattern, using some unknown qtIndexRange()
>> > function.
>> 
>> Really?
>> 
>>   (Python)
>>   for i in range(len(list))
>
> Am I the only one to think that this example is inherently broken ? I
> mean, why wouldn’t any sane person write :
>
>     for(auto const& element : list)
>         foo(element)
>
> or
>     std::for_each(list.begin(), list.end(), foo);
>
> Because :
> - it’s shorter
> - it’s more readable
> - it works for non random-access-container types
> - bonus : range checking is not needed, so it should be more performant
> - bonus : it doesn’t resort to a temporary value, same remark

What if you want to iterate over two lists.

for token,  cursors in zip(tokens,  cursors):
   ... 

is quite handy. 

You can use std::transform for some cases but C++ is sometimes very far behind. To my understanding Ranges should provide a good solution for it but they hide the type for good reasons. 

>
> Now, getting back to what Marc proposed initially, because the debate
> has gone far away from his initial proposal :
>
>> - template code (esp., but not necessarily only, when the type name
>> would require the use of 'typename')
>
> This is the one i’m not at ease with. Template code tends to be
> difficult to read, partly *because* there’s no type information. For
> readability concerns, i would prefer a local typedef named by the
> concept. Yes, that makes it two lines instead of one, but i think that’s
> one case where hinting the reader with a well-chosen type name makes a
> lot of sense.

Most typedefs I have seen was about hiding pointer or container types like CursorPointer or Cursors. But is CursorPointer a unique pointer,  a shared pointer and which flavor is it. Cursors is the same because it could be std::vector or QList. Some would hide a dictionary behind this name. So the typedef can be misleading. In that case I prefer auto. 

std::shared<Cursor> cursorPointer = document.cursorAtPostion(46);

CursorPointer cursorPointer = document.cursorAtPostion(46);

auto cursorPointer = document.cursorAtPostion(46);

I prefer the last but we need good tooling to show the type. It would be nice to have much more information like size,  is it movable or copyable. It is not only the type and we can provide that information. 

>> - all loop variables (both index and iterators)
>>   the reason being that spelling out the name is usually wrong:
>>  size_t i = stdVector.size() // wrong, should be
>>  std::vector::size_type...
>>  also helps when porting from Qt containers to STL ones
>
> That looks perfectly fine for me. Index based loops should be avoided
> whenever it is possible, and for iterator based loops auto makes no harm
> (seriously, who wants to write
> std::vector<my_very_long_type>::const_iterator instead of auto ?).
>
>> - all references to elements in a collection (same problem - way too
>> easy to misspell std::pair<int, int> for std::pair<const int, int>...)
>
> Same thing.
>
> Regards,
>
> Julien
>
> _______________________________________________
> Development mailing list
> Development at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development
Sent from cellphone 



More information about the Development mailing list