I wrote codes that listener and callback function like this:struct MyListener{    virtual void callback1(int value) = 0;    virtual void callback2(string value) = 0;    ...};vector<weak_ptr<MyListener>> _listeners;void MyClass::fireCallback1(int value){    vector<weak_ptr<MyListener>>::iterator iter = _listeners.begin();    while (iter != _listeners.end())    {        if ((*iter).expired())        {            iter = _listeners.erase(iter);        }        else        {            shared_ptr<MyListener> listener = (*iter).lock();            listener->callback1(value);            ++iter;        }    }}void MyClass::fireCallback2(string value){    vector<weak_ptr<MyListener>>::iterator iter = _listeners.begin();    while (iter != _listeners.end())    {        if ((*iter).expired())        {            iter = _listeners.erase(iter);        }        else        {            shared_ptr<MyListener> listener = (*iter).lock();            listener->callback2(value);            ++iter;        }    }}But as you see, when I add more functions on MyListener struct, I have to add fireCallbackN functions on MyClass, and it has too many duplicated codes.Is there best way to make simplify these duplicate codes in C++?
Listener callback functions
c++;c++11
Try this:struct MyListener{    virtual void on_data(int value) = 0;    // same function name    virtual void on_data(string value) = 0; // same function name    ...};template<typename T>void MyClass::trigger_data_event(T&& value) // pass by universal reference{    auto iter = _listeners.begin(); // consider using auto where appropriate    while (iter != _listeners.end())    {        // don't use expired here: it involves concurrency issues if the pointer        // is invalidated between calling expired and lock        // instead, just lock() and check the result:        if(auto p = iter->lock())        {            p->on_data(std::forward<T>(value)); // works with both callbacks            ++iter;        }        else            iter = _listeners.erase(iter);    }}I renamed the APIs you used from callback1/2 to on_data (same name) and unified the implementations of fireCallback1 and fireCallback2.