Skip to main content
gamedev.net
🔒 Locked

Template question

Started by Gage64 Jan 21, 2008 at 12:26 PM 4 replies 700+ views
Original Post
Gage64
Gage64
It's hard to explain what I want exactly, so I'll start with an example. The second argument in boost::shared_ptr's constructor is an object that will be used to delete the internal pointer. When creating a boost::shared_ptr, you don't have to specify it's type as an additional template parameter. For example:

SDL_Surface *s = SDL_LoadBMP("image.bmp");
boost::shared_ptr<SDL_Surface> sp(s, SDL_LoadSurface);
In the code above, you don't have to specify the type of SDL_LoadSurface, that is, you don't write:
boost::shared_ptr<SDL_Surface, void (*)()> sp(s, SDL_LoadSurface);
I am trying to do something similar, but I have one problem which the following code clearly demonstrates:

class A {
public:
    template <class T>
    A(T tt):t(tt) {}

    void func() {
        t(17);
    }

private:
    ??? t;
};

// Example usage:

struct Obj {
    void operator()(int i) {
        // ...
    }
};

void func() {
    A a(Obj());
}

My question is - how do I specify the type of 't'? I tried to figure out how boost does it, but quickly got lost in the code. Is there a simple solution? Thanks in advance.
smart_idiot
smart_idiot
#include <iostream>class A { private:  struct Base   {    virtual void func() = 0;    virtual ~Base() {}   };    template <typename T> struct Derived: public Base   {    T obj;    Derived(const T &obj): obj(obj)     {}        virtual void func()     {      obj();     }   };      A(const A&); // Don't want to deal with copying and assignment.   A & operator = (const A&);      Base *data;  public:      template<typename T>A(const T&obj): data(new Derived<T>(obj))    {}      ~A()    {     delete data;    }      void func()    {     data->func();    } };void hello() {  std::cout << "Hello!" << std::endl; }int main() {  A a(&hello);  a.func();  return 0; }
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other
ChaosEngine
ChaosEngine
Couldn't you just use boost.bind for this?
if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight
bulgurmayo
bulgurmayo
I have taken a look at how boost did :

class shared_count{...sp_counted_base * pi_;...  template<class P, class D> shared_count(P p, D d): pi_(0)  {    pi_ = new sp_counted_impl_pd<P, D>(p, d);    ...  }...};


With

template<class X> class sp_counted_impl_p: public sp_counted_base...



I suppose you could do the same :

class Stuff{...};template<class T>class StuffImpl : public Stuff{...};class A{public:  template <class T>  A(T tt): t(new StuffImpl<T>()) {}private:  Stuff*   t;};


[edit : fixed a typo]
Extrarius
Extrarius
The type of the second parameter is always going to be "void(*)(T*)", isn't it? If that is the case, it'd just be declared something like "template ". If it will adapt other function forms, it uses a simple wrapper as smart_idiot demonstrated.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.