How do I distinguish template arguments by a typedef?
Situation: I have lists (implemented as vectors) of several types. And I have a special StringList which I want to handle differently.
typedef std::vector<std::string> StringList;
inline void f(StringList const& list) {
...
}
template <typenamte T>
inline void f(std::vector<T> const& list) {
...
}
In cases where my variables are defined als StringList I would like to have the first version called, when a variable is defined as std::vector<std::string> I would like to have the second version called. But StringList and std::vector<std::string> call the first version. Using using gives the same behaviour.
If that is not possbile, an idea for a reasonable workaround would be nice.
Of course extending std::vector<std::string> would help, but since that is not a good idea at all I don't know how to distinguish them.
You have at least three options:
#include <vector>
#include <string>
// option 1
struct StringList : std::vector<std::string>
{
// optionally forward the constructors of std::vector that are called
};
// option 2
struct String : std::string
{
// optionally forward the constructors of std::string that are called
};
typedef std::vector<String> StringList;
// option 3
struct StringTag
{
};
typedef std::allocator<StringTag> StringAllocator;
typedef std::vector<std::string, StringAllocator> StringList;
The first and second options both require forwarding some of the constructors of the base class. The second option is probably better, based on the assumption that you probably only need to forward the std::string copy-constructor when adding strings to a string list.
The third option is my favourite - partly because it's a sneaky hack, but also because it requires no inheritance or forwarding. It works because the T argument of the allocator template-argument in a std container is never used.
EDIT: the C++ standard implies that the allocator's value_type must match the value_type of the container - so you can only use the third option if your standard library implementation allows it. If not, I would recommend the first or second options.
EDIT 2: See also: Is it wrong if the standard container element type and std::allocator type are different?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With