Reputation: 5648
I have a function f
:
template <typename T>
void f(T<int> ints)
{ /* */ }
This function is supposed to take std::vector<int>
or std::initializer_list<int>
or any other STL container, but only, if it contains int
.
I can live with it accepting other class
es with int
as a template parameter, but I don't want it to accept std::vector<char>
or std::vector<double>
or std::list<double>
or something like this.
How can I realize this?
Upvotes: 1
Views: 111
Reputation: 136256
Pedantically, that is a function template from which a function is instantiated.
One solution is to detect value_type
which standard containers provide:
template<class T>
typename std::enable_if<std::is_same<int, typename T::value_type>::value>::type
void f(T const& ints);
That will not work with built-in arrays though, as they do not have embedded value_type
. For built-in arrays you can add an overload:
template<size_t N>
void f(int const(&ints)[N]);
Upvotes: 1
Reputation: 65620
You could use a template template parameter:
template <template <typename...> typename T>
void f(const T<int>& ints)
{ /* */ }
But I would recommend using the value_type
type member of containers instead. This will avoid matching other templates with int
as the template parameter.
//using std::enable_if_t
template <typename T>
std::enable_if_t<std::is_same<typename T::value_type, int>::value>
f(const T& ints)
{ /* */ }
//or static_assert
template <typename T>
void f(const T& ints) {
static_assert(std::is_same<typename T::value_type, int>::value,
"T must be a container of ints");
//...
}
Upvotes: 5