问问题
1309 次
2 回答
10
delete
在检查它是否为d之前选择它要使用的函数。在复制构造函数可用且移动构造函数为delete
d 的情况下,移动构造函数仍然是两者中的最佳选择。然后它看到它是delete
d 并给你一个错误。
如果您有相同的示例,但实际上删除了移动构造函数,而不是将其delete
设为 d,您会看到它编译得很好并且确实回退到使用复制构造函数:
#include <iostream>
#include <memory>
using namespace std;
struct A {
unique_ptr<int> ref;
A(const A&a)
: ref( a.ref.get() ? new int(*a.ref) : nullptr )
{ }
A(const int i) : ref(new int(i)) { }
~A() = default;
};
int main()
{
A a[2] = { 0, 1 };
return 0;
}
此类根本没有为它声明移动构造函数(甚至没有隐式声明),因此无法选择它。
于 2014-07-11T09:07:58.267 回答
10
没有“后备”。它被称为重载决议。如果重载决议中有多个可能的候选者,则根据一组复杂的规则选择最佳匹配,您可以通过阅读 C++ 标准或其草案找到这些规则。
这是一个没有构造函数的例子。
class X { };
void func(X &&) { cout << "move\n"; } // 1
void func(X const &) { cout << "copy\n"; } // 2
int main()
{
func( X{} );
}
- 原样:打印“移动”
- 注释掉“1”:打印“copy”
- 注释掉“2”:打印“move”
- 注释掉“1”和“2”:编译失败
在重载决议中,将右值绑定到右值比左值到右值具有更高的优先级。
这是一个非常相似的例子:
void func(int) { cout << "int\n"; } // 1
void func(long) { cout << "long\n"; } // 2
int main()
{
func(1);
}
- 原样:打印“int”
- 注释掉“1”:打印“long”
- 注释掉“2”:打印“int”
- 注释掉“1”和“2”:编译失败
在重载解析中,精确匹配优于转换。
在您在此线程上的三个示例中,我们有:
1:两个候选函数;rvalue 更喜欢 rvalue(如我的第一个示例)
A(const A&);
A(A&&); // chosen
2:两个候选函数;rvalue 更喜欢 rvalue(如我的第一个示例)
A(const A&);
A(A&&); // chosen
3:一个候选函数;没有比赛
A(const A&); // implicitly declared, chosen
如前所述,在案例 3 中没有 A(A&&) 的隐式声明,因为您有一个析构函数。
对于重载决议,函数体是否存在并不重要,重要的是函数是否被声明(显式或隐式)。
于 2014-07-11T22:38:22.950 回答