2011-11-03 63 views
5

我有一些代码,可以大大的复杂性,通过使用lambda表达式减少。然而不幸的是,我们必须使用不完全支持C++ 11的编译器,我们不能轻松切换。现在的问题是如何保持逻辑尽可能接近与不可用的功能的λ表达(即std::function是可用的,lambda表达式都没有)。如何处理lambda表达式在拉姆达预编译

通常的解决办法是在其他地方定义函子,然后在适当的地方使用它:

struct functor{ 
    functor(type & member) : m_member(member) {} 
    void operator()(...) {...} 
    type & m_member; 
}; 

void function() { 
    use_functor(functor(...)); 
} 

我非常习惯这种模式,虽然我不喜欢它了很多。不定义类的主要原因通常是我将在STL中使用函数,而模板不喜欢函数内联定义的结构。然而,在我的情况下use_functor()功能将是一个通常的方法,所以可以定义函数本身内部的算符(各函子只有一个函数内使用)。

void function() { 
    struct functor{ 
     functor(type & member) : m_member(member) {} 
     void operator()(...) {...} 
     type & m_member; 
    }; 
    use_functor(functor(...)); 
} 

这似乎有所改善,但仍需要更多的丑陋的代码,我想。例如,我想彻底摆脱函子的名称。我知道有可能创建一个匿名结构,如果我只使用一个值。

void function() { 
    struct{ 
     // functor(type member) : m_member(member) {} 
     void operator()(...) {...} 
     // type & m_member; 
    } callback ; 
    use_functor(callback); 
} 

但是在这一点上我不知道如何提供必要的数据成员。由于结构是匿名的,它没有构造函数。我可以很容易地设置该成员,因为它是公开的,但是这又会增加一条我不喜欢的线。

的目标是把它的状态下,尽可能少地需要被改变,一旦我们切换到具有清洁lambda表达式,这将允许完全消除这一问题的编译器。

你怎么会去这样做呢?

+0

当我刚发现,一些老的GCC的甚至不处理来自嵌套函数到std ::功能<>很好的结构转换,而不会像任何的解决方案。所以我不得不使用选项一并分开逻辑。 – LiKao

回答

1

至于匿名struct的成员变量的initalisation没有一个构造函数,你可以这样做:

void function() { 
    type the_thing; 
    struct { 
     void operator()(...) {...} 
     type & m_member; 
    } callback = {the_thing}; 
    use_functor(callback); 
} 

callback设置type &参考m_member

0

扩大对答案的awoodland:

#define MY_LAMBDA(name, memberType, memberValue, body) \ 
    struct {          \ 
     void operator()(...) body    \ 
     memberType & memberValue;     \ 
    } name = {memberValue} 

void function() { 
    type thing_to_capture; 

    MY_LAMBDA(callback, type, thing_to_capture 
    { 
     std::cout << thing_to_capture << std::endl; 
    }); 

    use_functor(callback); 
} 

您可以使用MY_LAMBDA任何地方,你可以定义一个结构。不幸的是,如果没有可变宏,必须将所有捕获的对象包装到单个对象中,并且必须在“lambda声明”中指定该对象的类型。

另请注意,使用lambda的等效项为:

void function() { 
    type thing_to_capture; 

    auto callback = [&thing_to_capture]() 
    { 
     std::cout << thing_to_capture << std::endl; 
    }; 

    use_functor(callback); 
} 
+0

为了消除拼写错误的机会,您可以在宏的顶部添加'type thing_to_capture;'(如果您未调用显式c'tor或拷贝分配,如本例中所示)。 – Richard

+1

如果'MY_LAMBDA'没有能力指定operator()'的定义,它是如何有用的? – ildjarn

+0

@ildjarn好点...编辑即将到来。 –

0

您可以尝试提升lambda库或boost::phoenix。它们都被设计用来进行lambda样式操作,而不需要实际的lambda支持。由于它们是基于模板的,因此当某些事情无法按预期工作时,错误可能难以调试。