如果类具有显式构造函数,为什么lambda不能返回类对象? [重复]

问题描述 投票:1回答:1

这个问题在这里已有答案:

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

我试图使用lambdas从配置数据生成和初始化对象。我发现如果对象的类定义没有使用显式构造函数,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构造函数中删除'explicit'标记,代码编译就好了。

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

c++ lambda factory explicit
1个回答
2
投票

首先,查看有关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};
};
© www.soinside.com 2019 - 2024. All rights reserved.