考虑以下代码:
#include<iostream>
using namespace std;
struct A {
A(const A&){
cout<<"copy constructor"<<endl;
}
A(A&&){
cout<<"move constructor"<<endl;
}
~A(){
cout<<"destructor"<<endl;
}
static std::pair<A,int> f1()
{
int i = 1;
return std::pair<A,int>{i,2};
}
static std::pair<A,int> f2()
{
int i = 1;
return std::pair<A,int>{A(i),2};
}
private:
A(int){
cout<<"constructor"<<endl;
}
};
int main()
{
cout<<"f1: "<<endl;
A::f1();
cout<<"f2: "<<endl;
A::f2();
}
Run Code Online (Sandbox Code Playgroud)
构造函数A(int)是私有的,因此A不能pair<A,int>从 就地构造int。因此,在 中构建了一个临时的f1。在f2我显式创建临时文件但行为不同时,输出为:
f1:
constructor
copy constructor
destructor
destructor
f2:
constructor
move constructor
destructor
destructor
Run Code Online (Sandbox Code Playgroud)
我希望移动构造函数也被调用,A::f1但复制构造函数被调用,这是次优的。为什么会这样呢?
如果你看一下pair的构造函数
有趣的构造函数是 (2) 和 (3)
// (2)
constexpr pair( const T1& x, const T2& y );
// (3)
template< class U1 = T1, class U2 = T2 >
constexpr pair( U1&& x, U2&& y ); // SFINAE on constructible
Run Code Online (Sandbox Code Playgroud)
请注意,没有pair(T1&&, T2&&).
原来A(int)如此private,std::is_constructible_v<A, int>就是如此false。
因此f1,对于 ,只有 (2) 是可行的构造函数(因此是副本)。
对于f2,(3) 是可行的(并且匹配得更好),因此完成了前进(因此移动)。
| 归档时间: |
|
| 查看次数: |
149 次 |
| 最近记录: |