c++17 在编译时将 class 与删除的复制构造函数添加到 std::vector
c++17 add class with deleted copy constructor to std::vector at compile time
下面是我用删除的复制构造函数和复制赋值运算符定义的 class。这是唯一必须做出的假设。
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;
};
目标是在编译时将我的 class 添加到 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;
}
My compiler is telling me that the STL requires the use of my deleted copy constructor MyClass::MyClass(const MyClass&)
but is there any way around this?
不,你不能。
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 } };
如果你想避免抄袭,你必须像你说的那样坚持emplace_back
。
I am already aware of a possible way to add values at runtime ...
顺便说一下,您的示例不是 emplace_back
:
的正确使用方法
std::vector<MyClass> v;
v.emplace_back(MyClass{0});
v.emplace_back(MyClass{1});
v.emplace_back(MyClass{2});
您仍在创建 MyClass
,然后将其移至 v
,这是使用 emplace
-ish 函数时常见的错误。
你真正想做的大概是这样的:
v.reserve(3);
v.emplace_back(0);
v.emplace_back(1);
v.emplace_back(2);
这样你就可以避免意外地调用移动构造函数,并且只在正确的位置构造对象只有一次,没有移动,也没有复制.
The goal is then to add my class to a std::vector
at compile time.
如果要在编译时创建数组,请改用std::array
。
std::array
正是为此目的而设计的:
std::array<MyClass, 3> v = { 1, 2, 3 };
下面是我用删除的复制构造函数和复制赋值运算符定义的 class。这是唯一必须做出的假设。
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;
};
目标是在编译时将我的 class 添加到 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;
}
My compiler is telling me that the STL requires the use of my deleted copy constructor
MyClass::MyClass(const MyClass&)
but is there any way around this?
不,你不能。
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 } };
如果你想避免抄袭,你必须像你说的那样坚持emplace_back
。
I am already aware of a possible way to add values at runtime ...
顺便说一下,您的示例不是 emplace_back
:
std::vector<MyClass> v;
v.emplace_back(MyClass{0});
v.emplace_back(MyClass{1});
v.emplace_back(MyClass{2});
您仍在创建 MyClass
,然后将其移至 v
,这是使用 emplace
-ish 函数时常见的错误。
你真正想做的大概是这样的:
v.reserve(3);
v.emplace_back(0);
v.emplace_back(1);
v.emplace_back(2);
这样你就可以避免意外地调用移动构造函数,并且只在正确的位置构造对象只有一次,没有移动,也没有复制.
The goal is then to add my class to a
std::vector
at compile time.
如果要在编译时创建数组,请改用std::array
。
std::array
正是为此目的而设计的:
std::array<MyClass, 3> v = { 1, 2, 3 };