Overload function template using a templated type

1.1k Views Asked by At

I have a given function like this:

template <typename T, typename F>
T function(const F& f) const;

This function has various overloads, some of them concept based. Similar to the following:

template <typename T, std::integral F>
T function(const F& f) const;

template <typename T, std::same_as<double> F>
T function(const double& f) const;

Now I would like to add an overload using a templated type, similar to the following:

template <typename T, std::same_as<std::vector<V>> F>
T function(const std::vector<V>& f) const;

For this to work I need to specify the V type. But I could not find a syntax that allows specifying V without breaking the code.

The functions are called like this:

T result = function<T, F>(f);

This means, the template types are provided explictly and the overloads may not vary the number or order template parameters or else the compiler will complains.

How can this be solved?

3

There are 3 best solutions below

0
On BEST ANSWER

You have to write your own concept.

Adopted checking whether a class is a specialization from Check if class is a template specialization? and added a requires-clause to only accept the standard allocator.

template <class T, template <class...> class TT>
struct is_specialization : std::false_type {};

template <template <class...> class TT, class... Ts>
struct is_specialization<TT<Ts...>, TT> : std::true_type {};

template <class T, template <class...> class TT>
concept specializes = is_specialization<T, TT>::value;

template <typename T, specializes<std::vector> F>
T function(const F& f) const requires specializes<F::allocator_type, std::allocator>;

Unless the template-arguments may be provided manually, overload-resolution should work with the following overload though:

template <typename T, class V>
T function(const std::vector<V>& f) const;
3
On

I don't have access to a compiler to test this at the moment, but this should suffice:

template <typename T, typename V>
T function(const std::vector<V>& f) const;
0
On

Maybe using requires-clause?

template <typename T, typename F>
  requires std::same_as<std::vector<typename F::value_type>, F>
T function(const F& f) const;