1
votes

I'm new to c++ and Im learning to use templates . I want to make a template class with 2 template parameters,and to specialize a single member function from the class, for the case where the second template parameter is a vector templated on a pointer type of the first parameter. I think an example of what I tried will be more clear :

//Container.h:

template<class T ,   class CONT  >
class Container {

private:
    CONT container;
    T    someData;
public:
    void foo();
};

and the specilization for std::vector I tried is:

//Container.cpp

template<class T>
void Container<T, std::vector<T*> > ::foo(){
     cout << "specialized foo:  " << container.pop_back(); 
    }

template<class T, class CONT  >
void Container<T, CONT > ::foo(){
     cout << "regular foo: " << container.pop_back());
}

but I get these erors:

error C3860: template argument list following class template name must list parameters in the order used in template parameter list
error C2976: 'Container<T,CONT>' : too few template argument

the usage of the Container class has to be that the 1st parameter is some type , and second is an STL container, vector or list. for example :

Container<int, vector<int*> > c;
c.foo();

what am I dong wrong ?

2
Apart from the syntax errors, you cannot specialize function templates partially, so this approach doesn't work. - Kerrek SB

2 Answers

1
votes

Correct syntax to define a member function in Class template is

template<class T, class CONT > 
void Container<T, CONT>::foo()
{
     cout << "specialized foo:" ; 
}

foo() function is not overloaded and redefined. Redefinition of foo() function also gives error. You can't overload function on the basis of return type. The specialization of std::vector is incorrect. << operator should also be overloaded You can'y use it directly like this

cout << container.pop_back();

1
votes

You could use policy based design. Now there are many variations on this, but a simple example goes like so

#include <iostream>
#include <vector>

using namespace std;

template<typename T, class CONT>
struct foo_policy {
    static inline void execute() {
        cout << "regular foo: \n" ;
    }
};

template<typename T>
struct foo_policy<T, std::vector<T*>> {
    static inline void execute() {
        cout << "specialized foo: \n" ;
    }
};

template<class T ,   class CONT  >
class Container
{
private:
    CONT container;
    T    someData;
public:
    void foo()
    {
        foo_policy<T, CONT>::execute();
    }
};

int main() 
{
    Container<int, std::vector<int>>  a;
    Container<int, std::vector<int*>> b;
    a.foo();
    b.foo();
    return 0;
}

Here's a demo. In another scenario you could be deriving Container from the foo_policy class and using the base member's function (but there a bit more complex implications there)