Listener callback functions 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&lt;weak_ptr&lt;MyListener&gt;&gt; _listeners;

void MyClass::fireCallback1(int value)
{
    vector&lt;weak_ptr&lt;MyListener&gt;&gt;::iterator iter = _listeners.begin();
    while (iter != _listeners.end())
    {
        if ((*iter).expired())
        {
            iter = _listeners.erase(iter);
        }
        else
        {
            shared_ptr&lt;MyListener&gt; listener = (*iter).lock();
            listener-&gt;callback1(value);
            ++iter;
        }
    }
}

void MyClass::fireCallback2(string value)
{
    vector&lt;weak_ptr&lt;MyListener&gt;&gt;::iterator iter = _listeners.begin();
    while (iter != _listeners.end())
    {
        if ((*iter).expired())
        {
            iter = _listeners.erase(iter);
        }
        else
        {
            shared_ptr&lt;MyListener&gt; listener = (*iter).lock();
            listener-&gt;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++?
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&lt;typename T&gt;
void MyClass::trigger_data_event(T&amp;&amp; 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-&gt;lock())
        {
            p-&gt;on_data(std::forward&lt;T&gt;(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.