1

I have been writing in c++ for a few months, and i am comfortable enough with it now to begin implementing my own library, consisting of things that i have found myself reusing again and again. One thing that nagged me was the fact that you always had to provide a beginning and end iterator for functions like std::accumulate,std::fill etc...

The option to provide a qualified container was completely absent and it was simply an annoyance to write begin and end over and over. So, I decided to add this functionality to my library, but i came across problem, i couldn't figure out the best approach of doing so. Here were my general solutions:

1. Macros

- A macro that encapsulates an entire function call
ex. QUICK_STL(FCall)

- A macro that takes the container, function name, and optional args
ex. QUICK_STL(C,F,Args...)

2. Wrapper Function/Functor

- A class that takes the container, function name, and optional args
ex. quick_stl(F, C, Args...)

3. Overload Functions

- Overload every function in namespace std OR my library namespace
ex

namespace std { // or my library root namespace 'cherry' 
    template <typename C, typename T>
    decltype(auto) count(const C& container, const T& value);
}



I usually steer clear of macros, but in this case it could certainty save alot of lines of code from being written. With regards to function overloading, every single function that i want to use i must overload, which wouldn't really scale. The upside to that approach though is that you retain the names of the functions. With perfect forwarding and decltype(auto) overloading becomes alot easier, but still will take time to implement, and would have to be modified if ever another function was added. As to whether or not i should overload the std namespace i am rather skeptical on whether or not it would be appropriate in this case.

What would be the most appropriate way of going about overloading functions in the STD namespace (note these functions will only serve as proxy's to the original functions)?

Nowhere Man
  • 475
  • 3
  • 9
  • 3
    _I usually steer clear of macros_ **Ah, good...** _but in this case it could certainty save alot of lines of code from being written._ **Nooooo!!! It's a trap!!!** – erip Apr 23 '16 at 17:13

1 Answers1

1

You need to read this: Why do all functions take only ranges, not containers?

And This: STL algorithms: Why no additional interface for containers (additional to iterator pairs)?

I have been writing in c++ for a few months, and i am comfortable enough with it now to begin implementing my own library...

Let me look on the brighter side and just say... Some of us have been there before.... :-)

One thing that nagged me was the fact that you always had to provide a beginning and end iterator for functions like std::accumulate,std::fill etc...

That's why you have Boost.Ranges and the Eric's proposed ranges that seems like it isn't gonna make it to C++17.

  1. Macros

See Macros

  1. Wrapper Function/Functor

Not too bad...Provided you do it correctly, You can do that, that's what essentially Ranges do for Containers... See the aforementioned implementations

  1. Overload Functions

    • Overload every function in namespace std ...

Don't do that... The C++ standard doesn't like it.

See what the standard has to say

$17.6.4.2.1 The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.

Community
  • 1
  • 1
WhiZTiM
  • 21,207
  • 4
  • 43
  • 68