mardi 28 juillet 2015

Specialization after instantiation with in the context of pointers

take a look at the code below (this code is part of something bigger, I can not reproduce all of the code, but this is the idea).

template <typename T>
class Obs {
public:
    virtual ~Obs () {}
    virtual void process (T t) = 0;
};

template <typename T>
class Sub {
    vector<Obs<T>*> obs;
public:
    void add (Obs<T>& o) {
        // simplified
        obs.push_back (&o);
    }

    void run (T t) { 
        for (Obs<T>* v : obs) { 
            v->process (t);
        }
    }
};

struct Foo {};
class Interpreter : public Sub<Foo> {}; // (!)

//struct Xxx : public Obs<Foo> {}; // (1)

template <>
class Obs<Foo> {
public:
    void process (Foo foo) {
        cout << "foo" << endl;
    }
};

Usage:

Obs<Foo> obs_foo;
Interpreter intpr;

intpr.add (obs_foo);
intpr.run (Foo {});

So, I have Obs template class, which basically can be a base class for other classes, but in my case it is not used this way. I want to create an explicit specialization for particular type of T (for example for Foo type).

Commented line marked as (1) hopefully doesn't compile, but this code compiles even with line marked as (!).

If Sub class stores pointers to Obs classes in vector, what "kind" of pointer will be used in the context of Interpreter class (which derives from not yet implemented - by the user - Obs for Foo):

  1. Generated by the compiler (with virtual destructor and virtual process member function) or,
  2. Created by the user (explicit specialization)

I am asking this because this code compiles fine, but for couple of types it result in segmentation fault (from my observation it looks like if I write an explicit specialization of Obs class for my type - which results in segmentation fault - with virtual destructor and virtual member function it does not crash) and for others work well - nightmare!.

So, if answer for my question is the first one, if I move explicit specialization before definition of Interpreter class, the answer would be the second one? Would this code be a correct one?

Or maybe there is completely different reason which can cause problems?

(BTW. If you run this code, it probably will produce "foo", but it can also results in segfault)

Thanks,

Artur

Aucun commentaire:

Enregistrer un commentaire