C ++ 11模板编程,委托和lambda

时间:2015-10-19 19:48:10

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

所以,我解释这个问题有点困难,希望你们能得到它。

让我们说我尝试(只是为了好玩)使用没有堆分配和奇怪的(读取)事情来创建我自己的Delegate类,而只是模板。

这或多或少是这个计划。

template <class T> class IDelegate;

template <class R, class ...T> class IDelegate<R(T...)>
{
    public:

        virtual R run(T...) = 0;
        inline R operator() (T... args)
        {
            return run(args...);
        }

    // ...
};

template <class T> class Delegate;

template <class R, class ...T> class Delegate<R(T...)> : public IDelegate<R(T...)>
{
    public:
        Delegate(R(*function)(T...))
            : IDelegate<R(T...)>(IDelegate<R(T...)>::FUNCTION),
              function(function)
        {}

        Delegate(std::function<R(T...)>* stdf)
            : IDelegate<R(T...)>(IDelegate<R(T...)>::FUNCTIONAL),
              stdf(stdf)
        {}

        Delegate(std::function<R(T...)>& stdf)
            : IDelegate<R(T...)>(IDelegate<R(T...)>::FUNCTIONAL),
              stdf(stdf)
        {}

        virtual ~Delegate(){}

        R run(T... args)
        {
            if(IDelegate<R(T...)>::delegate_type == IDelegate<R(T...)>::FUNCTION)
                return function(args...);
            else
                return stdf->operator()(args...);
        }

    private:

        union
        {
            R(*function)(T...);
            const std::function<R(T...)>* stdf;
        };
};

// ...

template <class R, class ...T> Delegate<R(T...)> * delegate(std::function<R(T...)>& f)
{
    return new Delegate<R(T...)>(f);
}

该类已经与函数指针和方法很好地工作,我现在想要实现的是使它与lambdas一起使用并且通过使用std::function类来实现它基本上有两个原因:< / p>

  1. 目前比重新实施整个lambda事情更容易
  2. 它会使我的课程与std::function兼容,以供进一步使用。
  3. 这是一个使用lambdas的工作示例:

    auto f = new Delegate<void()>([]() { std::cout << "I'm a lambda!" << std::endl; });
    f->run();
    
    auto g = new Delegate<void(int)>([](int n) { std::cout << "Lambda: " << n << std::endl; });
    g->run(5);
    
    auto h = new Delegate<int(int)>(new std::function<int(int)>([&](int n) { return n*n; }));
    std::cout << h->run(5) << std::endl;
    

    当然,std::function 几乎总是被隐式调用,而std::function对象是在幕后构建的。

    但是,当我尝试使用delegate()辅助函数执行此操作时,它无法正常工作。

    auto e = delegate([]() { std::cout << "I'm a lambda!" << std::endl; });
    

    clang++出现以下错误。

    $ clang++ delegate5.cpp --std=c++11 -O3
    delegate5.cpp:263:11: error: no matching function for call to 'delegate'
            auto e = delegate([]() { std::cout << "I'm a lambda!" << std::endl; });
                     ^~~~~~~~
    delegate5.cpp:120:52: note: candidate template ignored: could not match 'R (*)(T...)' against '(lambda at delegate5.cpp:263:20)'
    template <class R, class ...T> Delegate<R(T...)> * delegate(R(*function)(T...))
                                                       ^
    delegate5.cpp:125:52: note: candidate template ignored: could not match 'function<type-parameter-0-0 (type-parameter-0-1...)>' against '(lambda at delegate5.cpp:263:20)'
    template <class R, class ...T> Delegate<R(T...)> * delegate(std::function<R(T...)>& f)
                                                       ^
    delegate5.cpp:130:67: note: candidate function template not viable: requires 2 arguments, but 1 was provided
    template <class O, class R, class ...T> Delegate<R(O::*)(T...)> * delegate(R(O::*method)(T...), O* parent)
                                                                      ^
    delegate5.cpp:135:67: note: candidate function template not viable: requires 2 arguments, but 1 was provided
    template <class O, class R, class ...T> Delegate<R(O::*)(T...)> * delegate(R(O::*method)(T...), O& parent)
                                                                      ^
    delegate5.cpp:140:73: note: candidate function template not viable: requires 2 arguments, but 1 was provided
    template <class O, class R, class ...T> Delegate<R(O::*)(T...) const> * delegate(R(O::*method)(T...) const, const O* parent)
                                                                            ^
    delegate5.cpp:145:73: note: candidate function template not viable: requires 2 arguments, but 1 was provided
    template <class O, class R, class ...T> Delegate<R(O::*)(T...) const> * delegate(R(O::*method)(T...) const, const O& parent)
                                                                            ^
    1 error generated.
    

    我想让它成功,可能是把它全部隐含起来,即使是在最后一个工作的lambda中,所以我可以实现类似的东西:

    auto e = delegate([]() { std::cout << "I'm lambda!" << std::endl; });
    auto g = delegate([](int n) { std::cout << "Lambda: " << n << std::endl; });
    auto h = delegate([&](int n) { return n*n; });
    

    很抱歉这篇长篇文章并提前致谢!

0 个答案:

没有答案