简体   繁体   English

如果从 lambda 表达式生成的类没有默认构造函数,那么如何创建生成的 class 类型的 object

[英]If classes generated from lambda expression do not have default ctor then how can an object of that generated class type be created

I am learning C++ using the resource listed here .我正在使用此处列出的资源学习 C++。 In particular, i read about lambda expressions in C++ Primer by Lippman.特别是,我在 Lippman 的 C++ Primer 中阅读了lambda 个表达式 There i came to know that lambdas are function objects.在那里我知道 lambda 是 function 个对象。 Moreover, classes generated from lambda expressions do not have a default constructor .此外,从 lambda 表达式生成的类没有默认构造函数 So take for example:举个例子:

auto wc = find_if(words.begin(), words.end(),
            [sz](const string &a){
                    return s.size() >= sz;
            };

It is written that the above lambda expression will generate a class that will look something like:据记载,上面的 lambda 表达式将生成一个 class,它看起来像这样:

class SizeComp {
    SizeComp(size_t n): sz(n) { } // parameter for each captured
variable
    // call operator with the same return type, parameters, and body as the lambda
    bool operator()(const string &s) const
        { return s.size() >= sz; }
private:
    size_t sz; // a data member for each variable captured by value
};

So what happens is that an unnamed object of this compiler generated class is created and is passed as the third argument to the std::find_if shown above.因此,会发生一个未命名的 object 这个编译器生成的 class 被创建并作为第三个参数传递给上面显示的std::find_if I can understand this.我能理解这一点。

Now it is my thinking/understanding that since this compiler generated class has no default ctor, so the third argument that is passed to the std::find_if must not be created using a default ctor since that would fail.现在我的想法/理解是,由于此编译器生成的 class 没有默认构造函数,因此不能使用默认构造函数创建传递给std::find_if的第三个参数,因为那样会失败。 So, internally the object that is passed should be created using the parameterized ctor something like:因此,在内部传递的 object 应该使用参数化的 ctor 创建,例如:

auto wc = find_if(words.begin(), words.end(), SizeComp(sz)); //note the third argument uses the parameterized ctor

My first question is that since there is no default ctor in case of an empty capture list in C++11 , so how will an object of that compiler generated class be created.我的第一个问题是,由于在 C++11捕获列表为空的情况下没有默认构造函数,因此将如何创建该编译器生成的 object class。 I mean in case of an empty capture list, there will be no data members inside the compiler generated class so there will be no parameterized ctor.我的意思是,在捕获列表为空的情况下,编译器生成的 class 中不会有数据成员,因此不会有参数化构造函数。 Which means that this compiler generated class has neither default nor parameterized ctor.这意味着此编译器生成的 class 既没有默认构造函数也没有参数化构造函数。 Then how can an object of this class be generated.那么这个class的一个object怎么生成呢。 For example, the situation shown below won't work when the capture list is empty:例如,当捕获列表为空时,如下所示的情况将不起作用:

auto wc = find_if(words.begin(), words.end(),
            [](const string &a){           //NOTE THE CAPTURE LIST IS EMPTY
                    return s.size() >= 5;
            };

Now, how will the third argument to std::find_if be created:现在,如何创建std::find_if的第三个参数:

auto wc = find_if(words.begin(), words.end(), CompGeneratedClass()); //this can't work because there is no default ctor

I also know that for a normal/ordinary user-defined class if we provide a user-defined ctor, then the compiler will not generate a default ctor for that class. So, it seems to me that since in case of an empty capture list lambda expression there is no user-defined ctor, the compiler should generate a default ctor for this compiler generated class. But the C++ standard says that there won't be a default ctor.我也知道,对于普通/普通用户定义的 class,如果我们提供用户定义的 ctor,那么编译器将不会为该 class 生成默认的 ctor。所以,在我看来,因为在捕获列表为空的情况下lambda 表达式没有用户定义的构造函数,编译器应该为此编译器生成一个默认构造函数 class。但是 C++ 标准说不会有默认构造函数。 So my second question is that why does this compiler generated class has different behavior than an user-defined class.所以我的第二个问题是为什么这个编译器生成的 class 与用户定义的 class 有不同的行为。


Also, note that this explanation is not only limited to C++ Primer by Lippman.另外,请注意,此说明不仅限于 Lippman 的 C++ Primer。 I've seen the same explanation in CppCon presentations as well.我也在CppCon演示文稿中看到了相同的解释。

The problem here is that of frame of mind.这里的问题是心态。 While the Primer is explaining the behavior in ways that one could easily understand, it is not to be taken literally.虽然 Primer 正在以人们容易理解的方式解释行为,但不要从字面上理解。 The normative text describes behavior, not ways to achieve it.规范文本描述的是行为,而不是实现它的方法。 A compiler doesn't actually need to create a class the same way we do.编译器实际上不需要像我们一样创建 class。

For instance, a vendor can always sneak in some secret tag into the constructor's parameter list.例如,供应商总是可以在构造函数的参数列表中加入一些秘密标签。 Imagine this is what it generates:想象一下,这是它生成的:

struct __secret_tag_at_src_line{};

struct __lambda_at_src_line{
   __lambda_at_src_line(__secret_tag_at_src_line, /*Other arguments*/)
   // ...
};

// ...

auto wc = find_if(words.begin(), words.end(), __lambda_at_src_line(__secret_tag_at_src_line{}, ...)};

We can't name that tag or even know of its existence, so we can't create the lambda on another line.我们不能命名那个标签,甚至不知道它的存在,所以我们不能在另一行创建 lambda。 And the class will never have a default constructor.而 class 永远不会有默认构造函数。 That's a way to do it.这是一种方法 But even then, a compiler doesn't have to do that.但即便如此,编译器也不必这样做。

The implementation is not bound by the same rules as us;实施不受与我们相同的规则约束; the standard gives great leeway to implementations, so long as the program is translated correctly.该标准为实现提供了很大的回旋余地,只要程序被正确翻译即可。 A compiler could just bless a byte and say "this is a lambda", no need to call a constructor.编译器可以只祝福一个字节并说“这是一个 lambda”,不需要调用构造函数。 Why?;为什么?; Because it accomplishes what the standard says, the observable behavior is intact (think about it? can the initialization of a capture-less lambda be observed by a C++ program?)因为它完成了标准所说的,可观察到的行为是完整的(想想看?C++ 程序可以观察到无捕获 lambda 的初始化吗?)

Sometimes implementations need to "cheat";有时实现需要“作弊”; heck, it's been known that implementations will call private constructors to get the job done .哎呀,众所周知,实现将调用私有构造函数来完成工作 But it's not really cheating, because the same rules do not apply.但这并不是真正的作弊,因为同样的规则并不适用。

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

相关问题 为什么为具有引用成员变量的类生成默认复制构造函数? - why default copy-ctor is generated for a class with reference member variable? 有模板副本ctor时未生成默认ctor - Default ctor not generated when there's a template copy ctor lambda 表达式生成的 function object 上的 c++ 属性? - c++ attributes on function object generated by a lambda expression? 在没有任何构造函数的类的情况下,在C ++ 11中自动生成类成员函数 - Automatically generated class member functions in C++11 in the case of classes which do not have any constructors 为什么我必须提供默认的ctor? - Why do I have to provide default ctor? 编译器为类生成noexcept ctor,而成员没有这样的保证 - Compiler generated noexcept ctor for class with members constructed with no such guarantee Swig:如何将生成的 C# 类的可访问性从“公共类”更改为“内部类” - Swig: How to change the accessiblity of the generated C# classes from `public class` to `internal class` 编译器如何从已删除的默认 ctor lambda 生成闭包? - How does the compiler generate a closure from a deleted-default-ctor lambda? 将使用基类ctor创建的对象转换为派生类 - convert an object created with base class ctor to a derived class 是否有必要为虚拟继承中的最基类设置默认构造函数? - Is it necessary to have default ctor for the most-base class in virtual inheritance?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM