Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Incorporating boilerplate vector<> code in C++

Tags:

c++

c++11

stl

There are certain functions I use in manipulating vector<T> that come up a lot but for which the standard interface is clunky.

For example, suppose v is if of type vector<T> for a typename T. Ideally I would like to make calls like:

 v.probe(x) //returns true if x is in v
 v.sort() // sort v
 v.unique() // unique elements of x
 v.locate(x) // pointer to the element in v equal to x if it exists, otherwise NULL
 v.cat(w) // concatenate vector w to x
 v.erase(x) // erase all x’s from v

and so on.

These can all be done in stl, but the interface is clunky and wordy. For example, v.probe(x) would be something like

 std::find(v.begin(),v.end(),x)!=v.end()

and v.sort is

std::sort(v.begin(),v.end())

which makes std::sort very awkward to use in the case of complex lvalue expressions, requiring a temporary. (I.e., I cannot easily sort foo->bar.names[3] without a temporary.

Getting unique values of v in STL is even more ridiculously clunky, requiring, I believe:

std::erase(std::unique(std::sort(v.begin(),v.end()).end(),v.end())

I assume that virtually every C++ programmer has run into this issue or issues like them.

What is the best way around this?

I have considered 3 options:

Write special purpose code for each type of vector<> I use in the code.

Write a template header for common vector functions

Have a personal vector<T> class K<T> that subclasses both vector<T> and a mixin class algorithm_vector<T> with the algorithms I need.

Option 1 seems simple but gets very wordy after a while. Option 2 is not as simple as it seems. Consider writing a special function probe, like

    template<typename T> probe(const vector<T> & v, const T &x)....

Well, the thing is that we actually only want to pass in x by reference if the size of T is large, otherwise we want to use value. I don’t even know how to write a template function that intelligently decides whether to pass its argument by value or reference, and, even if I did, it sounds hard to do.

Option 3 is probably the cleanest, but has semantic issues that make it unclear.

In conclusion, my question this: what is the best way to add common, simple generic functions on vectors to a program?

(Also, as an optional point which might shed some insight into this, I don’t understand why STL makes it so wordy and awkward to do common things like search a vector for an element, or sort a vector. Is there some reason that STL make the most common usages so wordy, and doesn’t overload to default on the whole container?)

like image 605
kdog Avatar asked Jan 09 '23 14:01

kdog


1 Answers

I would use neither approach and select using standard algorithms. They are well-known and any programmer who will read your code will understand what you are trying to do.:)

For example function

template<typename T> probe(const vector<T> & v, const T &x)....

will only confuse readers. When I see standard algorithm std::find I need not to scroll your code that to find the definition of the function. When I will see function probe I need to scroll your code that to find the function definition and to understand what the function does. :)

like image 100
Vlad from Moscow Avatar answered Jan 18 '23 23:01

Vlad from Moscow