Reputation: 1269
I want to write a C++ function like:
template <T<int> >
void printIntegers(T<int> ints) {
for (int i: ints) printf("%d ", i);
}
Because I want T<int>
to be either vector<int>
or list<int>
or any other STL container. How should I write the template parameter?
Upvotes: 0
Views: 235
Reputation: 3938
You could take a template template parameter as the argument:
template <template <typename...> typename Container>
void printIntegers(Container<int> ints) {
for (int i : ints) std::printf("%d ", i);
}
See https://en.cppreference.com/w/cpp/language/template_parameters#Template_template_parameter
As other answers have already suggested, though, taking by const reference may be preferable, and there are probably betters ways of doing your example anyway.
Upvotes: 4
Reputation: 25593
You simply use a template template parameter ( template template parameter subsection there ) like this:
template < template < typename > typename T > void printIntegers( T<int>& container )
{
for ( int el: container ) { std::cout << el << " " ; }
std::cout << std::endl;
}
int main()
{
std::vector<int> i{1,2,3,4};
std::list<int> l{7,8,9,10};
printIntegers( i );
printIntegers( l );
}
Some hints: In your code you did a copy instead of a reference by passing the container into your function. That will generate a lot of overhead by copying the content. The compiler may optimze it out, but you should write it with a reference to get a guarantee to not waste your memory with a copy.
Upvotes: 3
Reputation: 17454
Don't overthink it.
template <typename Container>
void printIntegers(const Container& container)
{
static_assert(std::is_same_v<typename Container::value_type, int>);
for (const auto& el : container)
{
printf("%d ", el);
}
}
Or even just:
template <typename Container>
void printThings(const Container& container)
{
for (const auto& el : container)
{
std::cout << el << ' ';
}
}
Upvotes: 4