4
votes

I have a general function that handles different containers.

template<template<class, class> class C, class T, class A>
void handle(C<T, A> const& c)
{
    cout << "General handling\n";
}

Now I would like it to react differently if I pass it a custom container. For simplicity's sake I first tried it with handling a vector in a separate way by trying to partially specialize this function for a vector.
This is what I thought it should look like.

template<class T, class A>
void handle<std::vector>(std::vector<T, A> const& c)
{
    cout << "vector handling\n";
}

However gcc gives the following error:

Could not execute the program Compiler returned: 1 Compiler stderr :16:36: error: template-id 'handle class std::vector>' in declaration of primary template 16 | (std::vector const& c) |

Can this be done with partial template specialization?

2

2 Answers

8
votes

Function templates can't be partial specialized; which only works with class templates and variable templates (since C++14). You can apply function template overloading instead.

e.g.

template<template<class, class> class C, class T, class A>
void handle(C<T, A> const& c)
{
    cout << "General handling\n";
}

template<class T, class A>
void handle(std::vector<T, A> const& c)
{
    cout << "vector handling\n";
}
2
votes

You can use functors too. With them you can partially specialize what you want

#include<iostream>
#include<vector>
#include <list>
template<template<class, class> class C, class T, class A>
struct handle {
    void operator()(C<T, A> const &c) {
        std::cout << "General handling\n";
    }
};

template<class T, class A>
struct handle<std::vector, T, A>{
    void operator()(std::vector<T, A> const& c)
    {
        std::cout << "vector handling\n";
    }
};
//To test
int main(){
    std::list<int, std::allocator<int>> ls(10,0);
    handle<std::list, int, std::allocator<int>>{} (ls);

    std::vector<int, std::allocator<int>> vec(10,0);
    handle<std::vector, int, std::allocator<int>>{} (vec);

}