简体   繁体   English

有没有更好的方法在C ++中实现类似Java的本地类?

[英]Is there a better way implementing Java-like local class in C++?

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. 有些情况下,当重载operator()不够或者我需要虚函数或其他东西时,我必须选择lambda上的本地类。

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. 如果函数具有不同的签名,则重载lambdas可以解决此类问题。 And I think this is one common problem since there is the lambda-overloading trick. 我认为这是一个常见问题,因为存在lambda-overloading技巧。
  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. 这是java世界中每天都会发生的事情。 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. 我必须给班级一个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. 至少在VC ++ 11中,lambda的捕获变量是私有的,所以我不能简单地继承lambda类。 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. 继承lambda类,至少在VC ++ 11中,需要一个变量(或者可能是其他一些占位符用于评估)lambda,这很难看。


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++. 在GCC 4.6上测试,无法像在VC ++中那样捕获局部变量的类型。 And captured variables are not exposed as in VC++. 捕获的变量不像VC ++那样公开。 LOL 大声笑

Ah, my bad. 啊,我的坏。 I forgot to turn C++11 on. 我忘了打开C ++ 11。 This works fine on G++. 这在G ++上运行正常。 But lambda types can't be inherited, and captured variables are still not exposed. 但是lambda类型不能被继承,并且捕获的变量仍然没有被暴露。

Not quite fine... Have to leave -fpermissive on. 不太好......不得不离开 - 坚持不懈。 Or G++ think the member variables conflict with local variables used in decltype(). 或者G ++认为成员变量与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. 我一直在徘徊为什么C ++选择了这样一个高级别的lambda用于闭包而不是更通用的本地类来捕获局部变量。

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. 确实有些情况下你需要别的东西,而不是简单的仿函数或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. 在函数内部本地创建复杂的行为在可读性和简单性方面不是一个好主意,并且肯定会违反该函数的SRP。
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. 在许多情况下,如果您必须编写多个operator() ,这意味着您将需要重用已编写的代码,如果它在本地类中,则无法执行。

Meaning: In most cases it will be the best solution to write a proper class, outside the function, with proper constructors and so on. 含义:在大多数情况下,使用适当的构造函数等在函数外部编写适当的类将是最佳解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM