iDevGames Forums
Template specialization of a method - Printable Version

+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Game Programming Fundamentals (/forum-7.html)
+--- Thread: Template specialization of a method (/thread-5320.html)



Template specialization of a method - Fenris - Jul 10, 2005 06:49 AM

I have a templatized base class, and I want to specialize one of its methods (to control its return type). That means I define the class, let's say, as template <typename T> A. Now, all of its member functions need to be:
Code:
template <typename T> A<T>::MyFunc
Surely that can't be necessary? Isn't there a better way to specialize just one of the methods? Do I need to typedef it in some way?


Template specialization of a method - OneSadCookie - Jul 10, 2005 02:32 PM

eg.

Code:
template <class T>
class X
{
public:
    T foo(int x)
    {
        return T(x);
    }
};



Template specialization of a method - Fenris - Jul 11, 2005 12:22 AM

Aaah, thanks.


Template specialization of a method - Fenris - Jul 11, 2005 05:17 AM

Right, I'm going to have to ask for some more help and insight here...

What I'm trying to achieve is a base class for a singleton, so that all my singleton classes can be derived off of it. So, I set about to create it, and it worked fairly well, apart from one little caveat:
Code:
static class bmSingleton* Instance (void) {return _instance;}
When I subclass a singleton from that, for instance BaseManager, I can't go:
Code:
myManager::Instance()->subclassedManagerData
because the return type of the instance is bmSingleton, not BaseManager, and subclassedManagerData isn't in bmSingleton. So, I have to cast the result of the Instance call to whatever type I expect it to be. Very cumbersome. Then, as if that wasn't enough, the static member in bmSingleton is static for bmSingleton which means that there isn't a static instance pointer for each singleton type, but only a single static instance pointer for all singletons, which is completely useless.

So, what I wanted to do was then to templatize this bmSingleton class so that I can pass in the type of the subclass and get the correct return type of the Instance() method, and a static instance pointer for each singleton type.

My header:
Code:
template <class T>
class bmSingleton
{
    protected:
    static T* instance;
    public:
    bmSingleton (void);
    ~bmSingleton ();
    
    static T* Instance (void)
    {
        return instance;
    }
};
template <class T> T* bmSingleton::instance = NULL;

Question #1: Is this even feasible? Will I actually get a separate instance pointer for each template class? Or will they still share some kind of confused instance pointer?
Question #2: The final line gives me a 'syntax error before ::' - any guesses as to why?
Question #3: Is it at all possible to send the bmSingleton, as a template type parameter, a subclass of itself? Can it contain a pointer to a subclass of itself?

All insight is very appreciated.


Template specialization of a method - OneSadCookie - Jul 11, 2005 02:45 PM

singleton.hpp
Code:
#ifndef singleton_hpp
#define singleton_hpp

template<class T>
class Singleton
{
public:
    static T* instance()
    {
        return &_instance;
    }

protected:
    Singleton() {}
    
private:
    Singleton(const Singleton &);
    Singleton &operator = (const Singleton &);
    
    static T _instance;
};

template<class T> T Singleton<T>::_instance;

#endif
x.hpp
Code:
#ifndef x_hpp
#define x_hpp

#include <stdio.h>

#include "singleton.hpp"

class X : public Singleton<X>
{
public:
    X() : x(0) {}
    
    void foo() { printf("%d\n", x++); }
    
private:
    int x;
};

#endif
bar.cpp
Code:
#include "x.hpp"

void bar()
{
    X::instance()->foo();
}
main.cpp
Code:
#include "x.hpp"

extern void bar();

int main(int argc, const char *argv[])
{
    X::instance()->foo();
    bar();
    
    return 0;
}