Frank
Frank

Reputation: 4417

C++ template partial specialization question

I'm having compile time trouble with the following code:

  template <typename T, 
            template <class T, class Allocator = std::allocator<T> > class C>
  bool is_in(const C<T>& a, const C<T>& b);

  template <typename T, std::vector> // HERE
  bool is_in(const std::vector<T>& a, const std::vector<T>& b)
  {
    return false; // implementation tbd
  }

...

vector<int> a, b;

cout << is_in(a,b) << endl;

The error message is (on the line marked "HERE"):

error: 'std::vector' is not a type

(of course, I have included vector from std!). Any suggestion? I fiddled with it for a while, but I'm getting to the point where I could use some help :-) I need to partially specialize the initial template declaration so that I can have the compiler switch implementations depending on the actual type of the container C (there will be a is_in for sets, one for vectors, one for ranges..., with different algorithms each time).

Thanks!

Upvotes: 5

Views: 2677

Answers (3)

Christian Rau
Christian Rau

Reputation: 45968

I don't know if it works (as template templates are always a trouble to my mind), but what about just trying

template <typename T>
bool is_in(const std::vector<T>& a, const std::vector<T>& b)
{
    ...
}

as it's a specialization.

EDIT: Others have clarified on this already, but I'll add it for completeness. The above code is actually an overload and not a partial specialization, but partial function specializations aren't allowed anyway.

Upvotes: 0

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361792

The partial specialization of a function template is not allowed by the Standard.

A simple solution is : use overload.

template <typename T> 
bool is_in(const std::vector<T>& a, const std::vector<T>& b)
{
  return false; // implementation tbd
}

This is overloaded function template. Its NOT partial specialization.

Or, you could do this:

namespace detail
{
    template<typename T, typename C>
    struct S
    {
        static bool impl(const C & a, const C & b)
        {
            //primary template
            //...
        }
    }
    template<typename T>
    struct S<T, std::vector<T> >
    {
        static bool impl(const std::vector<T> & a, const std::vector<T> & b)
        {
            //partial specialization for std::vector
            return false;
        }
    }
}

template <typename T,  template <class T, class Allocator = std::allocator<T> > class C>
bool is_in(const C<T>& a, const C<T>& b)
{
   return detail::S<T, C<T> >::impl(a,b);
}

Upvotes: 6

Luc Danton
Luc Danton

Reputation: 35469

Function template partial specialization is not allowed. In any case you're not using the template specialization syntax, you're actually writing an additional overload. Try this instead:

template <typename T>
bool is_in(const std::vector<T>& a, const std::vector<T>& b)
{
    return false; // implementation tbd
}

If partial specialization were allowed, it would look like this instead:

template <typename T> // std::vector is not a template parameter,
                      // so we wouldn't put it here
bool is_in<T, std::vector>(const std::vector<T>& a, const std::vector<T>& b)
// instead, it'd appear ^ here, when we're specializing the base template
{
    return false; // implementation tbd
}

Upvotes: 1

Related Questions