Fitzwilliam Bennet-Darcy
Fitzwilliam Bennet-Darcy

Reputation: 1342

How can I write a template function that takes a generic C++ standard library container

I have a function that needs to be able to work for different container types, for example

void foo(const std::vector<bar>& param1, const std::vector<double>& params2)

and

void foo(const std::list<bar>& param1, const std::list<double>& params2)

where bar is a class that I've written. The function body itself uses generic C++ standard library functions.

Is there a way I can templatise this? I have tried

template<typename T> void foo(const T<bar>&, const T<double>&)

But this gives the compiler error

error C2988: unrecognizable template declaration/definition

I'm using MSVC2015.

Upvotes: 2

Views: 159

Answers (3)

Some programmer dude
Some programmer dude

Reputation: 409166

There are basically three solutions:

  1. Use template template arguments.

  2. Use iterators (which is what the standard library itself uses)

  3. Use different templates for different arguments, and let the compiler deduce the actual types. With your function it would be something like

    template<typename T, typename U> void foo(const T&, const U&);
    

Solution 2 is the recommended one if you just need to iterate over the contents of the container. Solution 3 is the recommended one if you need access tot he container itself.

Upvotes: 4

Maarten Bamelis
Maarten Bamelis

Reputation: 2423

So-called template template arguments will allow you to write the desired code (as also shown in other answers or over on CppReference).

Alternatively, you could also write generic functions that accept iterators. This is exactly how the functions in the <algorithm> are implemented. I tend to believe that functions that accept iterators are actually more flexible as the caller can decide what range needs to be processed by the function.

Upvotes: 0

songyuanyao
songyuanyao

Reputation: 172894

You should declare T as template template parameter to indicate that it's a template-name (and needs arguments to be instantiated), e.g.

template<template <typename...> class T> 
void foo(const T<bar>&, const T<double>&);

LIVE

Upvotes: 4

Related Questions