我遇到了这个古玩,并且不明白为什么使用显式构造函数会导致此操作失败。
我试图使用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构造函数中删除“ explicit”标记,则代码可以正常编译。
有人可以启发我为什么不能在此lambda中明确显示构造函数吗?
答案 0 :(得分: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};
};