Is it possible to create function-local closures pre-C++11?

烈酒焚心 提交于 2019-12-03 16:46:59

bind1st only works for binary functions, and in general it's very restricted. mem_fn works with non-static member functions only; for your application you would want ptr_fun.

Really the best tool for the job in C++03 is Boost Bind, or I'll demonstrate here with tr1::bind which is (in my opinion) more portable.

#include <tr1/functional>
#include <iostream>
#include <algorithm>

using namespace std::tr1::placeholders;

int nums[] = { 1, 2, 4, 5, 6, 8 };

int main() {
    struct is_multiple {
        static bool fn( int mod, int num ) { return num % mod == 0; }
    };

    int *n = std::find_if( nums, nums + sizeof nums/sizeof*nums,
                        std::tr1::bind( is_multiple::fn, 3, _1 ) );

    std::cout << n - nums << '\n';
}
Ben Voigt

Yes you can, but you'll have to implement one or more virtual methods declared in an interface.

template<typename Arg, typename Result>
struct my_unary_function
{
    virtual Result operator()(Arg) = 0;
};

template<typename Arg, typename Result>
struct my_unary_functor
{
    my_unary_function<Arg, Result> m_closure;
    my_unary_functor(my_unary_function<Arg, Result> closure) : m_closure(closure) {}
    Result operator()(Arg a) { return m_closure(a); }
};

template<typename T, TFunctor>
void some_templated_function( std::vector<T> items, TFunctor actor );

Then you can define and use a local closure:

void f()
{
    std::vector<int> collection;

    struct closure : my_unary_function<int, int>
    {
        int m_x, m_y;
        closure(int x, int y) : m_x(x), m_y(y) {}
        virtual int operator()(int i) const { cout << m_x + m_y*i << "\t"; return (m_x - m_y) * i; }
    };

    some_templated_function( collection, my_unary_functor<int,int>(closure(1, 5)) );
}

Credit to @Omnifarious for this improvement (my_unary_functor not needed):

void f()
{
    std::vector<int> collection;

    struct closure : my_unary_function<int, int>
    {
        int m_x, m_y;
        closure(int x, int y) : m_x(x), m_y(y) {}
        virtual int operator()(int i) const { cout << m_x + m_y*i << "\t"; return (m_x - m_y) * i; }
    };

    // need a const reference here, to bind to a temporary
    const my_unary_functor<int,int>& closure_1_5 = my_unary_functor<int,int>(closure(1, 5))
    some_templated_function( collection, closure_1_5 );
}

If this was doable in C++03, why would C++0x have introduced lambdas? There's a reason lambdas exist, and it's because binding and all the other C++03 solutions suck hideously.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!