我在这里缺少什么?为什么我不能将矢量作为类构造函数的一部分移动?从构造函数中删除const也没有帮助。
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class Bar
{
public:
Bar(const vector<unique_ptr<char>> vec);
vector<unique_ptr<char>> vec_;
};
Bar::Bar(const vector<unique_ptr<char>> vec) :
vec_(move(vec)) //not ok
{
}
int main()
{
vector<unique_ptr<char>> vec;
vec.push_back(unique_ptr<char>(new char('a')));
vec.push_back(unique_ptr<char>(new char('b')));
vec.push_back(unique_ptr<char>(new char('c')));
vector<unique_ptr<char>> vec1 (move(vec)); //ok
Bar bar(vec1);
return 0;
}
答案 0 :(得分:2)
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class Bar
{
public:
Bar(vector<unique_ptr<char>> vec);
vector<unique_ptr<char>> vec_;
};
Bar::Bar(vector<unique_ptr<char>> vec) : // If you intend to move something,
// do not make it const, as moving
// from it will in most cases change
// its state (and therefore cannot be
// const-qualified).
vec_(move(vec))
{
}
int main()
{
vector<unique_ptr<char>> vec;
vec.push_back(unique_ptr<char>(new char('a')));
vec.push_back(unique_ptr<char>(new char('b')));
vec.push_back(unique_ptr<char>(new char('c')));
vector<unique_ptr<char>> vec1 (move(vec));
Bar bar(std::move(vec1)); // Just like the line immediately above,
// the explicit `move` is required, otherwise
// you are requesting a copy, which is an error.
return 0;
}
我保留了其余代码,但您可能需要阅读Why is “using namespace std;” considered bad practice?
答案 1 :(得分:2)
此代码适用于我:
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
struct Bar
{
Bar(vector<unique_ptr<char>> vec)
: Vec(move(vec))
{ }
vector<unique_ptr<char>> Vec;
};
int main()
{
vector<unique_ptr<char>> vec;
vec.push_back(unique_ptr<char>(new char('a')));
vec.push_back(unique_ptr<char>(new char('b')));
vec.push_back(unique_ptr<char>(new char('c')));
vector<unique_ptr<char>> vec1(move(vec));
Bar bar(move(vec1));
}
请注意,我删除了构造函数参数中的const
,并在move
中构建bar
时添加了显式main()
。
事实上,您在main()
中使用了此代码:
vector<unique_ptr<char>> vec1 (move(vec)); //ok Bar bar(vec1);
但是,在构建vec1
时,该代码需要bar
向量的副本。由于vec1
被定义为vector
unique_ptr
,并且由于unique_ptr
可移动但无法复制,因此编译器发出错误:无法复制vec1
向量。
相反,如果要触发向量参数的移动,则必须明确调用std::move()
参数上的vec1
。
答案 2 :(得分:1)
此构造函数(带或不带const)接受矢量按值:
Bar::Bar(const vector<unique_ptr<char>> vec)
传值意味着通过复制传递的参数构造向量vec
。但是,unique_ptr
不可复制。因此,只能使用xvalue调用此函数(即,即将被销毁的临时向量,或者通过调用std::move
或其他方式明确允许移出的向量)。
所以要调用这个构造函数:
Bar bar( vec1 ); // FAIL: not allowed to take a copy of vec1
Bar bar( std::move(vec1) ); // OK: move pointers out of vec1 in order to create bar
可以通过非{const引用Bar::Bar
获取向量来避免此问题。但是,如果构造函数将元素移出其参数,这将导致不直观的行为,因此您拥有它的方式可能是最好的。
问题的第二部分是Bar::Bar
在您实际设法调用它之后所做的事情。在这个版本中:
Bar::Bar(const vector<unique_ptr<char>> vec) : vec_(move(vec))
它失败了,因为你无法移出const
向量。要解决此问题,请取出无用的任何目的const
。 (问题的第一部分不受参数是否为const
)的影响。