使用带有回调的可变参数模板

时间:2016-07-20 18:06:07

标签: c++ templates c++11

我正在使用简单的“委托”系统开展游戏。

这是源文件(抱歉法国评论):

#ifndef C_DELEGATE_HPP_
#define C_DELEGATE_HPP_


#include <list>
#include <functional>

#include <boost/function.hpp>


namespace ns
{


////////////////////////////////////////////////////////////////////////////////
/// Classe gérant une liste de callback. Les callbacks ont entre 0 et 1
/// arguments.
///
template <typename ... Args>
class C_Delegate
{

public:

    ////////////////////////////////////////////////////////////////////////////
    /// Type des callbacks.
    ///
    typedef std::function<void (Args...)> callback;




    ////////////////////////////////////////////////////////////////////////////
    /// Structure répresentant un callback.
    ///
    struct S_Callback
    {

        callback    callback_ptr;

        bool        once;

    }; // S_Callback




    ////////////////////////////////////////////////////////////////////////////
    /// Type pour la liste des callbacks.
    ///
    typedef std::list <S_Callback> callback_list;



public:

    ////////////////////////////////////////////////////////////////////////////
    /// Constructeur.
    ///
    C_Delegate (void)
    { }


    ////////////////////////////////////////////////////////////////////////////
    /// Destructeur.
    ///
    virtual ~C_Delegate (void) throw ()
    { }




    ////////////////////////////////////////////////////////////////////////////
    /// Connecte une fonction à la liste des callbacks.
    ///
    /// @param cb : Callback.
    /// @param instance : Instance de l'objet utilisant le callback.
    /// @param once : Détermine si le callback est appelé que une fois ou non.
    ///
    void connect (callback cb, bool once=false) throw ()
    {

        _callbacks.push_back ( {cb, once} );

    }


    ////////////////////////////////////////////////////////////////////////////
    /// Déconncte une fonction de la liste.
    ///
    /// @param cb : Callback.
    /// @param instance : Instance de l'objet utilisant le callback.
    ///
    void disconnect (callback cb) throw ()
    {
        for (auto i = _callbacks.begin(); i != _callbacks.end(); i++) {
            if (i->callback_ptr == cb) {
                _callbacks.erase(i);
                return;
            }
        }
    }




    ////////////////////////////////////////////////////////////////////////////
    /// Appels tous les callbacks lé à l'objet actuel.
    ///
    /// @param a1 : Argument à passer aux callbacks.
    ///
    void emit(Args... args) throw ()
    {
        for (auto i = _callbacks.begin(); i != _callbacks.end(); i++)
        {
            i->callback_ptr(args...);

            if (i->once)
                _callbacks.erase (i);
        }
    }



private:

    ////////////////////////////////////////////////////////////////////////////
    /// Liste des callbacks.
    ///
    callback_list   _callbacks;


}; // C_Delegate


} // namespace ns

#endif

linter什么也没说,好。但是,与C_Delegate<void>一起使用会产生此错误:invalid parameter type 'void'

如何让我的C_Delegate::emit方法允许不使用参数回调?

感谢您的回答!

2 个答案:

答案 0 :(得分:3)

空参数包的拼写为<>而不是<void>。尝试使用C_Delegate<>

顺便说一句,它们被称为可变参数模板,varargs通常引用C ...

答案 1 :(得分:1)

使用C_Delegate<>代替C_Delegate<void>而不是{{1}}。