3

There are situations that I have to choose local classes over lambda when overloading operator() is not enough or when I need virtual functions or something else.

um.. for example:

  1. I need a object that captures local variables, and holds more than one functions, which are, unfortunately of same signature.

    • Overloading lambdas can solve such problem if the functions are of different signatures. And I think this is one common problem since there is the lambda-overloading trick.
  2. I need a object that capture local variables and inherits some other class or have member variables.

    • This is something happens everyday in the java world. Dynamic polymorphism has its usefulness, at least sometimes.

What I'm doing now, is defining some helper macros like these:

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

And put them into the local class:

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);

And this is ugly.

I have to refer a same variable three times.

I have to give the class a name for ctor.

I have to give a variable name for the closure, though I think this cannot be helped under the current standard.

At least in VC++11, captured variables of a lambda are private, so I cannot simply inherit the lambda class. And inheriting lambda class, at least in VC++11, needs a variable (or maybe some other placeholders for the evaluation) for the lambda, which is ugly.


And I think I don't even know if the standard allows me to capture the type of local variables in a local class this way...

Tested on GCC 4.6, local variable's type can't be captured as in VC++. And captured variables are not exposed as in VC++. LOL

Ah, my bad. I forgot to turn C++11 on. This works fine on G++. But lambda types can't be inherited, and captured variables are still not exposed.

Not quite fine... Have to leave -fpermissive on. Or G++ think the member variables conflict with local variables used in decltype().


I've been wandering why C++ has chosen such a high-leveled lambda for closure instead of more generic local class that can capture local variables.

BlueWanderer
  • 2,671
  • 2
  • 21
  • 36
  • 2
    What are you trying to achieve? **C++ lambdas can capture *local* variables**. – Nawaz Apr 30 '13 at 06:27
  • @Nawaz but lambdas cannot define member functions other than operator(), cannot define member variables, cannot inherit base class, and thus cannot do object polymorphism. – BlueWanderer Apr 30 '13 at 06:42
  • 1
    Again: what are you trying to *achieve*? You describe some pattern here that you seem to use often (if not, what's the problem?). Since it is not an usual pattern it's possible that the problem you try to solve with it has another, more usual solution. So please explain the core problem, not the problem with your solution to that core problem. – Arne Mertz Apr 30 '13 at 06:53
  • @ArneMertz Actually this is not targeting some specific problem at all. Just for a cleaner way to capture local variables and produce a more complex object than function object as simple as lambda, which is too simple. – BlueWanderer Apr 30 '13 at 07:17
  • 1
    So...use a class functor? If you require extra functions or polymorphism in a lambda, it's probably not going to be simple, and so probably shouldn't be a lambda anyway. – Yuushi Apr 30 '13 at 07:39

1 Answers1

0

This is going to be more than fits into a simple comment on your question, so I'll make it an answer.

There are indeed cases where you want something else and more complex than a simple functor or lambda. But these cases are very different and diverse, there is no "one fits all" solution, especially none that fits into a few lines and that will not blow the scope of a single function.
Creating complex behavior on the fly locally inside a function is not a good idea in terms of readability and simplicity, and most surely will violate the SRP for the function.
In many cases, if you have to write more than a single operator(), that means you will want to reuse the code you have written, which cannot be done if it is inside a local class.

Meaning: In most cases it will be the best solution to write a proper class, outside the function, with proper constructors and so on.

Arne Mertz
  • 24,171
  • 3
  • 51
  • 90
  • Actually the only reason I want to put class inside a function is for the readability and simplicity. Moving things outside breaks the continuity of the logic when it does, and that's when one wants to leave things inside. And I think polymorphism itself doesn't make a single responsibility no longer single. – BlueWanderer Apr 30 '13 at 08:45