0

I wouldn't be shocked if this is just a mess and there's a way better way of doing it, but here's what I'm working with.

I have a base class Foo, and all of the derived classes are singletons. Rather that write instance functions for each of the derivations I want to template it in Foo since it'll always be the same thing.

template<typename T>
class Foo{
  private:
    static T single;

  public:
    static T* instance();

    virtual void fun() = 0;
};

template<typename T>
T Foo<T>::single;

template<typename T>
T* Foo<T>::instance(){
    return &single;
}
class A : public Foo<A>{
  public:
    void fun();
};

class B...

class C...

The trouble happens when I'm trying to make a class Bar which would have a vector of pointers to types of Foo. It would be treated as a stack, and would run code from the Foo on top, along with code as they're pushed or popped.

class Bar{
  private:
    std::vector</*types of Foo<T>*/> fooStack;

  public:
    void init();
    void updateFoo();
    void pushFooStack(Foo* f);
    void popFooStack();
};

#include "FooA.h"

void Bar::init(){
    //Run Box initializing code
    pushFooStack(A::instance())
    return;
}

void Bar::updateFooStack(){
    if(!fooStack.empty()){
        //Run Foo<T> update code.
    }
    return;
}

void Bar::pushFooStack(Foo* f){
    if(!fooStack.empty()){
        //Run Foo<U> pause code
        fooStack.pop_back();
    }
    fooStack.emplace_back(f);
    //Run Foo<U> push code
    return;
}

void Bar::popFooStack(){
    if(!fooStack.empty()){
        //Run Foo<T> pop code
        fooStack.pop_back();
    }
    if(!fooStack.empty()){
        //Run Foo<U> resume code
    }
    return;
}

I can't have a vector to a templated class, and I've seen all sorts of suggestions to similar problems like creating some class IFoo, or using std::unique_ptr or boost::variant, but each of them seems to run into its own problem, often some form of "Undefined reference to Foo::instance or "invalid template parameter"/"Type/value mismatch". Perhaps I'm missing something on those solutions though.

If anyone knows how I can get this to work, or maybe just a better way entirely to set this whole thing up then I'd love to hear it. Not having to rewrite the same instance function for each derivation of Foo would be nice, but it at least works so if getting this to work is a hassle in its own right that's also an option.

Thank you in advance, anyone who can help me out.

  • 1
    A template class can have a non-template base. Beyond that, can you explain what you're trying to achieve by having a vector of pointers to singletons? Without that description, this look like an XY problem - you're trying to achieve X, think that some Y may provide a solution to X, so you ask how to do Y. You're more likely to get a useful options if you ask how to do X (which may have many possible solutions) rather than asking how to do Y (which may or may not have a solution). – Peter Aug 21 '19 at 22:17
  • Gotta say that title raised an eyebrow. `vector` of pointers to singleton sounds very odd. Why would you have more than one of a singleton? Notes: you can't override a static variable. `static` and `virtual` don't mix. I was imagining something CRTP-ish, so I went to look it up and... [voilà!](https://stackoverflow.com/questions/34222703/how-to-override-static-method-of-template-class-in-derived-class) That said, this won't help with the `vector` part of the job. – user4581301 Aug 21 '19 at 22:34
  • Obligatory drawing of attention to [Meyer's Singleton](https://stackoverflow.com/a/1008289/4581301). – user4581301 Aug 21 '19 at 22:38

1 Answers1

0

I would not use the singleton pattern for this. Assuming that we want to update the Foos that we have in the Bar object we could just have Foo derive from IFoo but with no templating. If you really want to make sure that it's only ever instanced once you could have a static bool within its constructor that you set when it's called and assert or throw an exception in the case that it's already set when running through it.

If there's a good reason for using the singleton pattern, most likely what you want to do is to have a non template interface that the template class derives from and that interface is what you then store a pointer to within your Bar array.

Hope this helps?