【问题标题】:Why can't a lambda return a class object if the class has explicit constructors? [duplicate]如果类具有显式构造函数,为什么 lambda 不能返回类对象? [复制]
【发布时间】:2019-08-28 09:57:54
【问题描述】:

我遇到了这个古玩,不明白为什么使用显式构造函数会导致失败。

我尝试使用 lambda 从配置数据生成和初始化对象。我发现如果对象的类定义不使用显式构造函数,lambda 只能返回对象的副本。此代码示例是我发现的一个简单示例。

class foo {
public:
    explicit foo() : _a(0) {}
    explicit foo(int val): _a(val) {}
    explicit foo(const foo& o) : _a(o._a) {}
    explicit foo(foo&& o) : _a(std::move(o._a)) {}
    foo& operator()(const foo& rhs) { if (this != &rhs) { _a = rhs._a; } return *this; }
    foo& operator()(foo&& rhs) { _a = std::move(rhs._a); return *this; }
    int a() const { return _a; }
    void a(int val) { _a = val; }
private:
    int _a;
};

auto makeFoo = [](int val) -> foo { return foo(val); };

示例代码编译失败,makeFoo 行出现以下错误:

In static member function ‘static foo<lambda(int)>::_FUN(int)’:
error: no matching function for call to ‘foo::foo(foo)’

但是,如果我从 foo 构造函数中删除“显式”标签,则代码编译得很好。

有人能告诉我为什么构造函数不能在这个 lambda 中显式吗?

【问题讨论】:

  • 很确定你也会有同样的错误,如果不使用 lambda,使用 normal 函数
  • 是的,我刚刚查过了。它与 lambda 无关。这都是关于如何分配返回值的。

标签: c++ lambda factory explicit


【解决方案1】:

首先,查看有关explicit 关键字的文档。

指定构造函数或转换函数(C++11 起)是显式的,即不能用于隐式转换和复制初始化。

基本上,显式拷贝构造函数意味着拷贝构造函数不会被隐式调用。

您不需要定义复制/移动构造函数,编译器会为您生成它们。复制/移动分配也是如此。只需删除它们就可以了。

class foo {
public:
    foo() = default;
    explicit foo(int val): _a(val) {}
    int a() const { return _a; }
    void a(int val) { _a = val; }
private:
    int _a{0};
};

【讨论】:

  • 我知道编译器会为我创建复制/移动构造函数。这不是我要问的问题。这更多是为什么当构造函数是显式的时返回值会停止。我想我没有想到返回值仍在分配,即使那行代码中有构造,并且显式复制/移动构造函数阻止分配。所以,一般来说,复制/移动构造函数不应该是显式的。初始化构造函数可以是。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-04
  • 1970-01-01
  • 2013-01-10
  • 2013-11-25
  • 2012-11-28
  • 1970-01-01
相关资源
最近更新 更多