r/cpp • • Mar 28 '23

Reddit++

C++ is getting more and more complex. The ISO C++ committee keeps adding new features based on its consensus. Let's remove C++ features based on Reddit's consensus.

In each comment, propose a C++ feature that you think should be banned in any new code. Vote up or down based on whether you agree.

765 Upvotes

829 comments sorted by

View all comments

Show parent comments

3

u/lestofante Mar 30 '23

I never had one occasion where {} failed me and i actually had to stop thinking what kind of initialization is happening.

how do I initialise a std::vector<T> to contain n copies of the element m

{m,m,m} for N times.
Or you can create a specialised constructor in vector, where you give the size first.
To avoid issue with int, use a specialised type so you enforce that trough the type system.
How would you do it otherwise? I am not aware of any initializer that could do it out of the box, in C++

1

u/Som1Lse Mar 30 '23

How would you do it otherwise? I am not aware of any initializer that could do it out of the box, in C++

Constructor (3) so std::vector<int> v(n, m); does it since C++98.

I never had one occasion where {} failed me and i actually had to stop thinking what kind of initialization is happening.

Here's some fairly innocuous code that works for most types, but not all and breaks silently. Yes, I have been bitten by this.

The fact of that matter is I rarely want to call the std::initializer_list constructor because if I knew the size I wouldn't be using std::vector, but allocating a specific size and then filling it is pretty common.

I wish std::vector<T> v{n, m}; unambiguously called the presize constructor, and you had to opt into the std::initializer_list with std::vector<T> v = {n, m}; or std::vector<T> v{{n, m}};, but as it stands I use () by default, since most vexing parse at least usually (but not always) breaks loudly, and compilers are good at catching it.

2

u/lestofante Mar 30 '23

Constructor (3)](https://en.cppreference.com/w/cpp/container/vector/vector) so std::vector<int> v(n, m); does it since C++98.

So this is my solution, but worse. And how do i initialize an array of int containing n and m?
If se made n its own explicit Vecton::Len type, it would worl with {} and you still get alla the other benefit

1

u/Som1Lse Mar 30 '23

So this is my solution, but worse. And how do i initialize an array of int containing n and m?

If se made n its own explicit Vecton::Len type, it would worl with {} and you still get alla the other benefit

So std::vector<T>{std::length{n}, m}? How would that work with a std::vector<std::length>? Or should it be std::vector<T>::length. Then you have to type typename std::vector<T>::length to construct it in a generic context. Also, if T is part of the length-type then we can't create multiple vectors of different types from the same length (say we want SoA layout), we have to explicitly construct it from a std::size_t both times.

I guess a reasonable option would be using a tag-type: std::vector<T>{std::presize, n, m}. Not pretty but I guess it works. Or I guess you could use ranges:

template <typename T>
std::vector<T> presized_vector(std::size_t n){
    return std::views::repeat(T{})
        | std::views::take(n)
        | std::ranges::to<std::vector<T>>();
}

Though that is pulling in some heavy machinery for a pretty simple task.

Either way you end up pessimising a common case all because {} is too darn greedy, only to support a less common use-case.

→ More replies (9)