C++ Type Erasure for function parameters

  c++, type-erasure

So in Java we have generics, whereby I’m looking to achieve something similar to the following in C++

public interface ListenerIF <T> {
    public void onChange(T eventData);
}

...

public static void main(String[] args) {
    List<ListenerIF<String>> foo = ...;
    List<ListenerIF<Integer>> bar = ...;
    foo.add((strUpdate) -> {/*some string operation*/});
    bar.add((intUpdate) -> {/*some math*/});
    foo.forEach((listener) -> listener.onChange("some change"));
    bar.forEach((listener) -> listener.onChange(123));
}

But with C++ templates fundamentally being different (and needing all implementations up front), I’m trying to understand how to accomplish something similar in C++ using type erasure (and since the JVM is written in C++, I’m quite certain it’s possible and just eluding me).

I can get type erasure where I want it in terms of ListenerIF, but I can’t figure out how to make type T dynamic for the function ListenerIF::onChange(T). This is what I’ve arrived at for getting ListenerIF working (without T being dynamic, and here just as std::string):

class ListenerIF {
  public:
    //how do I get the parameter to this function to be dynamic?
    virtual void onChange(std::string) = 0;
};

template<typename LISTENER>
class Listener: public ListenerIF {
  public:
    //how do I get the parameter to this function to be dynamic?
    void onChange(std::string update) {
      l.onChange(update);
  private:
    LISTENER l;
};

class Foo {
  public:
    //how do I get the parameter to this function to be dynamic?
    void onChange(std::string);
};
class Bar {
  public:
    //how do I get the parameter to this function to be dynamic?
    void onChange(std::string);
};

void Foo::onChange(std::string update){}
void Bar::onChange(std::string update){}

int main() {
  std::vector<ListenerIF *> listeners;
  listeners.push_back(new Listener<Foo>());
  listeners.push_back(new Listener<Bar>());
  for(std::vector<ListenerIF *>::iterator listenersItr = listeners.begin(); listenersItr < listeners.end(); listenersItr++){
    (*listenersItr)->onChange("some string update");
}

Which is all fine if I just want to ‘onChange’ to just be for strings, but if I want to have a completely different ‘onChange’ type to be an int, float, or some other object type then this breaks down.

Am I just not understanding something simple that I’ve left out?

Source: Windows Questions C++

LEAVE A COMMENT