std::vector<> aFoo(3) type clang plugin request ? =)

Bjoern Michaelsen bjoern.michaelsen at canonical.com
Sat Jun 20 04:16:20 PDT 2015


Hi,

On Sat, Jun 20, 2015 at 10:23:40AM +0100, Michael Meeks wrote:
> 	And I was wondering ... could there be a clang plugin for that ? in
> general I think it's prolly a good swap to discard the use-case of
> someone wanting <N> default-initialized items at the front of a vector
> and always warn on it ;-)

Killing the 1-argument vector fill constructor:

 std::vector< basebmp::Color > aDevPal(2);

in general is probably a Good Thing(tm). It can just be too misleading.
Requiring at least the explicit two-value fill constructor for the rare cases where
someone wants a filled vector isnt too much to ask and less prone to
misunderstandings:

 std::vector< basebmp::Color > aDevPal(2, basebmp::Color(0,0,0));

Although that _still_ might be misleading[1], so turning all those into the
somewhat longer, but more explicit:

 std::vector< basebmp::Color > aDevPal;
 aDevPal.reserve(2);
 aDevPal.push_back(...);
 ...

> 	So I suppose the check would be for a size reservation on a vector
> followed by push_back - rather than some array indexing - does that make
> sense ? or did I go crazy ;-)

Yes, in general you want neither of the above forms. Preferably instead of
e.g.:

 std::vector< basebmp::Color > aDevPal(2);
 aDevPal[0] = basebmp::Color( 0, 0, 0 );
 aDevPal[1] = basebmp::Color( 0xff, 0xff, 0xff );

you would -- if possible -- simply:

 std::vector< basebmp::Color > aDevPal{
    basebmp::Color( 0, 0, 0 ),
    basebmp::Color( 0xff, 0xff, 0xff ) };

and only for complex cases, where you do not have the elements statically
available, something like:

 std::vector< foo > vFoos;
 vFoos.reserve(vInput.size());
 std::transform(std::back_inserter(vFoos),
     vInput.begin(),
     vInput.end(),
     [] (decltype(vInput)::value_type aInputValue) { return do_something(aInputValue); });

see also:
https://skyfromme.wordpress.com/2015/03/02/50-ways-to-fill-your-vector/
https://skyfromme.wordpress.com/2015/03/12/following-the-white-rabbit/
(tl;dr: Use initializer lists to fill vectors when possible).

Best,

Bjoern

[1] Well, except that:
     std::vector<int>(3, 0)
    is doing something different from:
     std::vector<int>{3, 0}
    just to make things more interesting. But hey, that's C++ for you.
    But that wart exists for the 1-arg ctor too -- yet another reason to kill that.


More information about the LibreOffice mailing list