下面是我用删除的副本构造函数和副本赋值运算符定义的类。这是唯一必须做的假设。
class MyClass
{
public:
explicit MyClass(int i) : i(i) {}
MyClass(const MyClass&) = delete;
MyClass& operator=(const MyClass&) = delete;
MyClass(MyClass&& other) :
i(std::move(other.i))
{}
MyClass& operator=(MyClass&& other) {
i = std::move(other.i);
return *this;
}
private:
int i;
};
然后目标是在编译时将我的类添加到std :: vector。
int main()
{
std::vector<MyClass> v{MyClass{0}, MyClass{1}, MyClass{2}};
return 0;
}
我的编译器告诉我STL要求使用我删除的副本构造函数MyClass::MyClass(const MyClass&)
,但是有什么办法吗?
我已经知道在运行时添加值的一种可能方法,但是我认为下面的解决方案不理想,因为我丢失了编译时间检查。
int main()
{
std::vector<MyClass> v;
v.emplace_back(MyClass{0});
v.emplace_back(MyClass{1});
v.emplace_back(MyClass{2});
return 0;
}
我的编译器告诉我STL要求使用我删除的副本构造函数
MyClass::MyClass(const MyClass&)
,但是有什么办法吗?
不,你不能。
[initializer_list
]为您创建一个隐藏数组,该数组被声明为const
,其估计如下:
// pseudo code
const MyClass __arr[3] = { MyClass(1), MyClass(2), MyClass(3) };
std::vector<MyClass> v{ std::initializer_list<MyClass>{ __arr, __arr + 2 } };
[如果要避免复制,则必须按照您所说的那样坚持[C0]。
我已经知道在运行时添加值的可能方法...
顺便说一句,您给出的示例是not使用emplace_back
的正确方法:
emplace_back
您仍在创建std::vector<MyClass> v;
v.emplace_back(MyClass{0});
v.emplace_back(MyClass{1});
v.emplace_back(MyClass{2});
,然后将其移至MyClass
,这在使用v
-ish函数时是一个很常见的错误。
您真正想要做的可能是:
emplace
这样,您就避免了[[偶然地调用move构造函数,而只是在正确的位置构造对象只有一次,没有任何动作,并且没有副本。
目标是在编译时将我的类添加到v.reserve(3);
v.emplace_back(0);
v.emplace_back(1);
v.emplace_back(2);
。
如果要在编译时创建数组,请改用std::vector
。std::array
正是为此目的而设计的:
std::array