我有一个类,我将其称为NonCopyable,该类无法复制,但可以移动(构造移动和分配移动)。我正在尝试构造一个std::pair<const int, NonCopyable>
,但是下面的行将无法编译。
std::pair<const int, NonCopyable>(1, NonCopyable());
我收到的错误是:
no matching function for call to 'std::pair<const int, NonCopyable>::pair(int, NonCopyable)'
为什么该行无法编译?由于NonCopyable是可构造/可移动的,所以我希望它使用构造函数template<class U1, class U2> constexpr pair(U1&& x, U2&& y)
。
编辑:
所以我遗漏了一些我认为不相关的信息,但实际上是并且非常重要。
我有一个类ContainsNC,它包含一个不可复制的类NonCopyable。我正在尝试构造一个std::pair<const int, ContainsNC>
,但是下面的代码无法编译。
#include <utility>
#include <thread>
#include <iostream>
struct NonCopyable {
NonCopyable() = default;
NonCopyable(const NonCopyable&) = delete;
NonCopyable(NonCopyable&&) = default;
NonCopyable& operator=(const NonCopyable&) = delete;
NonCopyable& operator=(NonCopyable&&) = default;
};
class ContainsNC {
public:
~ContainsNC() {
std::cout << "destruct" << std::endl;
}
private:
NonCopyable nc;
};
int main() {
std::pair<const int, ContainsNC>(1, ContainsNC());
}
现在,如果注释掉ContainsNC的自定义析构函数,则代码将编译。为什么自定义析构函数会影响std::pair<const int, ContainsNC>
的构造?
答案 0 :(得分:2)
有一条规则说When destructor is defined, move operations are deleted and they are not generated by compiler default.
所以您必须在类中添加move构造函数。
class ContainsNC {
public:
~ContainsNC() {
std::cout << "destruct" << std::endl;
}
ContainsNC(ContainsNC&&) = default;
private:
NonCopyable nc;
};
在添加move ctor之后,默认的构造函数被删除,您还必须提供它来编译代码:
class ContainsNC {
public:
~ContainsNC() {
std::cout << "destruct" << std::endl;
}
ContainsNC() = default;
ContainsNC(ContainsNC&&) = default;
private:
NonCopyable nc;
};
您可以检查this link来查看编译器何时为类默认值生成了移动操作。