3

在某些情况下,当重载 operator() 不够或需要虚函数或其他东西时,我必须选择本地类而不是 lambda。

嗯..例如:

  1. 我需要一个捕获局部变量的对象,并拥有多个函数,不幸的是,它们具有相同的签名。

    • 如果函数具有不同的签名,则重载 lambda 可以解决此类问题。我认为这是一个常见问题,因为存在 lambda 重载技巧。
  2. 我需要一个捕获局部变量并继承其他类或具有成员变量的对象。

    • 这是 Java 世界每天都会发生的事情。至少在某些时候,动态多态性有它的用处。

我现在正在做的是定义一些像这样的辅助宏:

#define CAPTURE_VAL(Var) decltype(Var) Var
#define CAPTURE_REF(Var) decltype(Var) &Var
#define INIT_CAPTURE(Var) Var(Var)

并将它们放入本地类:

struct Closure
{
    Closure(CAPTURE_VAL(var1), CAPTURE_REF(var2)) : INIT_CAPTURE(var1), INIT_CAPTURE(var2)
    {
    }

    int foo()
    {
        return some_expression;
    }

private:

    CAPTURE_VAL(var1);
    CAPTURE_REF(var2);

} closure(var1, var2);

这很丑陋。

我必须引用同一个变量三次。

我必须给这个类起一个ctor的名字。

我必须为闭包提供一个变量名,尽管我认为在当前标准下这无济于事。

至少在 VC++11 中,捕获的 lambda 变量是私有的,所以我不能简单地继承 lambda 类。并且继承 lambda 类,至少在 VC++11 中,需要一个用于 lambda 的变量(或者可能是其他一些用于评估的占位符),这很难看。


而且我想我什至不知道标准是否允许我以这种方式捕获本地类中的局部变量的类型......

在 GCC 4.6 上测试,局部变量的类型不能像在 VC++ 中那样被捕获。并且捕获的变量不会像在 VC++ 中那样公开。哈哈

啊,我的坏。我忘了打开 C++11。这在 G++ 上运行良好。但是 lambda 类型不能被继承,捕获的变量仍然没有暴露。

不太好......必须离开 -fpermissive 。或者 G++ 认为成员变量与 decltype() 中使用的局部变量冲突。


我一直在想为什么 C++ 选择了如此高级的 lambda 来进行闭包,而不是更通用的可以捕获局部变量的局部类。

4

1 回答 1

0

这不仅适合对您的问题的简单评论,因此我将其作为答案。

在某些情况下,您需要比简单的仿函数或 lambda 更复杂的东西。但是这些情况非常不同和多样,没有“一刀切”的解决方案,尤其是没有一个适合几行并且不会破坏单个功能的范围的解决方案。
就可读性和简单性而言,在函数内部动态创建复杂行为并不是一个好主意,而且肯定会违反函数的 SRP。
在许多情况下,如果您必须编写多个operator(),这意味着您将希望重用您编写的代码,如果它在本地类中则无法做到这一点。

含义:在大多数情况下,最好的解决方案是在函数之外编写一个适当的类,并使用适当的构造函数等等。

于 2013-04-30T08:19:31.900 回答