I think I was too hasty to make that claim.
In any event, "generic" code is code that's supposed to work with more than one type.
Many excellent examples can be found in the standard library. For example, std::vector is generic, since we can put almost anything in a vector. Indeed, the authors of
std::vector took great effort making sure it works with as many types as possible, because this improves flexibility and reduces code duplication.
In general, generic code has some interest in being able to handle as many different things as possible. This is done by minimizing the requirements imposed on the inputs.
For example, the lambda that looks like this
1 2
|
auto max_size = [](auto... args)
{ return std::max({args.size()...}); };
| |
Does a okay job of finding the largest container from its arguments. But it requires that all of
args have a size member function that returns something copyable and comparable; and that all of
args.size() has the same type, and all of
args can be copied, and some other things.
Semantically, however, the minimum we need out of an argument to
max_size is that
a.) we can get a size
b.) we can compare two sizes.
If we really wanted to eliminate all the unnecessary requirements we would obtain code only a language expert can understand. But just to be able to pass in things like arrays is perhaps desirable. Right now we can never do it, because an array never has a size member function. Switching from a member to a free-function gains us some flexibility for cheap, because we can overload or specialize free functions / function templates however we want.
1 2 3 4 5 6
|
using std::size;
std::size_t size(char const* str)
{ return std::strlen(str); }
auto biggest = [](auto... args)
{ return std::max({size(args)...}); };
| |
How you solve this problem depends on what the intent is. You're probably best following Peter87's suggestion here, unless you're concerned with passing things other than strings.