4

How to make partial specialization of the class GList so that it is possible to store pointers of I (i.e I*) ?

template <class I>
struct TIList
{
    typedef std::vector <I> Type;
};


template <class I>
class GList
{
      private:
            typename TIList <I>::Type objects;
};
Peter Alexander
  • 53,344
  • 14
  • 119
  • 168
Woody
  • 69
  • 2
  • 6

2 Answers2

7

You don't need to specialise to allow that. It can store pointers already.

GList<int*> ints;

Anyway, if you wanted to specialise GList for pointers, use the following syntax.

template <class I>
class GList<I*>
{
    ...
};

Then just use I as you would in any normal template. In the example above with GList<int*>, the pointer specialisation would be used, and I would be int.

Peter Alexander
  • 53,344
  • 14
  • 119
  • 168
  • And the specialized class GList must have own implementation of the private data member objects? – Woody Jan 22 '11 at 14:03
  • Yes, the specialisation shares nothing with the original base template. You have to write all the member variables and member functions again (or factor them out into a common base class if possible). – Peter Alexander Jan 22 '11 at 14:40
  • I need a different code inside a method processing ponters. I tried to specialize only method for pointers: void GList method (){...} and void GList method {...}. But compiler does not recognize differences between them.... – Woody Jan 22 '11 at 14:58
  • Yeah, you can't specialise individual member functions of a template class, you have to specialise the whole class. The usual workaround is to take all the common parts shared between the two into a common base class and have them both inherit from it. – Peter Alexander Jan 22 '11 at 15:05
5

Previous post states that you don't NEED to specialize for pointer types, but you might.

Consider the following:

struct Bar {
    void bar(void) { /* do work */ }
};

template <class T> struct Foo {
    T t;

    void foo(void)
    {
        t.bar(); // If T is a pointer, we should have used operator -> right?
    }
};

int main(int argc, char * argv[])
{
    Foo<Bar *> t;

    t.foo();
}

This won't compile. Because in Foo::foo we have a pointer yet we use it as variable.

If you add the following, it will use the specialization and compile fine:

// This is a pointer to T specialization!
template <class T> class Foo<T *> {
    T * t;
public:
    void foo(void)
    {
        t->bar();
    }
};
MatiasFG
  • 576
  • 2
  • 8
  • That's a really, really bad idea. You should *never* change semantics in a specialisation. When you do that, you end up with things like `std::vector`. What happens if I use `Foo` with an `std::shared_pointer`? It's not going to use reference semantics, so are you going to specialise for all conceivable smart pointers as well? – Peter Alexander Jan 22 '11 at 10:56
  • Down-vote only because you think this is a (really really) bad idea? This is a valid case of when a specialization is needed, what you are talking about is a design issue. – MatiasFG Jan 23 '11 at 14:02