c ++事件队列,可变参数函数,静态函数和其他奇怪的东西

时间:2014-10-04 19:31:06

标签: c++ c++11 static variadic-templates

在昨天How to implement a simple event queue?的咆哮之后,我决定最终实现c ++ 11的大跃进。就在c ++ 14出现之前可能......

无论如何,我发现变量函数是这个愉快的努力的完美前进方向。它们可能并不是真的,但无论如何,我设法窃取了我在某处发现的一些代码,并最终得到了这个代码:

#include <iostream>
#include <functional>
#include <queue>

class Event
{
public:
    int timeOfCompletion;
    std::function<void()> function;
    inline bool operator<(const Event& target) const
    {
        return target.timeOfCompletion < timeOfCompletion;
    }
};

class System
{
public:

    int someValue;
    std::priority_queue<Event> funcs;

    System()
    {
        someValue = 100;
    }

    template<typename Func, typename...Args>
    void addFunctionToQueue(const int t , const Func&& myFunc, Args&&... myArgs)
    {
        Event newEvent;
        std::function<void()> func = std::bind( std::forward<Func>(myFunc), std::ref(myArgs)...);
        newEvent.function = func;
        newEvent.timeOfCompletion = t;
        funcs.push(newEvent);
    }

    void runAllFunctions()
    {
        while(!funcs.empty())
        {
            Event func = funcs.top();
            funcs.pop();
            func.function();
        }
    }

    static void doStaticFunction(int a)
    {
        std::cout <<"I would like to change someValue here, but can't :-(\n";
        //someValue -= a;//invalid
    }

    void doNonStaticFunction(int a)
    {
        someValue -= a;
        std::cout <<"Set someValue to " << someValue << "\n";
    }

};

int main()
{
    System newSystem;

    newSystem.doNonStaticFunction(5);

    newSystem.addFunctionToQueue(5, System::doStaticFunction, 1);
    newSystem.runAllFunctions();

    //newSystem.addFunctionToQueue(5, newSystem.doStaticFunction, 1);// is invalid
    //newSystem.addFunctionToQueue(5, System::doNonStaticFunction, 1);// is invalid
    //newSystem.addFunctionToQueue(5, newSystem.doNonStaticFunction, 1);// is invalid
    std::cin.ignore();
    return 0;
}

无论如何,我怎样才能获得&#34; addFunctionToQueue&#34;功能与非静态功能一起使用?我以为我有更多问题,但我想如果我能得到答案,那么我的其他问题将有希望得到解决......

1 个答案:

答案 0 :(得分:1)

  1. const参数中删除Func限定符。

    template<typename Func, typename...Args>
    void addFunctionToQueue(int t , Func&& myFunc, Args&&... myArgs)
    //                              ~~~^ no const
    
  2. 原理:当使用带有模板参数推导的转发引用(或左值引用)类型时,会自动推导出const限定符(取决于论证的限定词)。明确地禁止编译器将其添加到Func类型本身,这会在您尝试std::forward<Func>时导致错误。也就是说,您需要编写std::forward<const Func>来避免编译错误,但仍然没有意义,因为const T&&不是转发引用

    1. 非静态成员函数需要一个将被调用的对象,就像您编写a.foo()而不是foo()一样。

      newSystem.addFunctionToQueue(5, &System::doNonStaticFunction, &newSystem, 1);
      //                                                            ~~~~~~~~~^ context