追加到联合向量
Appending to vector of union
我有一个联合,定义如下:
union CellType {
std::string str;
int i;
double d;
Money<2> m; // Custom class for fixed-decimal math.
};
然后,我有一个这样的联合向量。
std::vector<CellType> csvLine;
我的问题是,如何将一个值附加到向量的末尾?我通常将 push_back
用于 vector
的字符串、整数等,但是当向量元素是并集时,我无法完全弄清楚语法。任何帮助将不胜感激。
(是的,这个 class 一次读取一行 CSV 文件,如果这有什么不同的话。)
这是失败的 MRE
#include <vector>
#include <iostream>
union CellType {
std::string str;
int i;
double d;
// Money<2> m; // Custom class for fixed-decimal math.
};
int main() {
std::vector<CellType> csvLine;
CellType c;
c.str = "foo";
csvLine.push_back(c);
}
Money 被注释掉了,因为与 MRE 无关
错误
Severity Code Description Project File Line Suppression State
Error C2280 'CellType::CellType(void)': attempting to reference a deleted function ConsoleApplication1 C:\work\ConsoleApplication1\ConsoleApplication1.cpp 22
如果您使用的是 C++11 之前的编译器,那么:
Unions cannot contain a non-static data member with a non-trivial
special member function (copy constructor, copy-assignment operator,
or destructor).
和std::string具有non-trivial以上所有功能。
如果您使用的是支持 C++11 的编译器:
If a union contains a non-static data member with a non-trivial
special member function (copy/move constructor, copy/move assignment,
or destructor), that function is deleted by default in the union and
needs to be defined explicitly by the programmer.
If a union contains a non-static data member with a non-trivial
default constructor, the default constructor of the union is deleted
by default unless a variant member of the union has a default member
initializer.
这基本上意味着您没有任何联合构造函数,您需要自己定义复制或移动构造函数才能使以下行起作用:
csvLine.push_back(c);
as push_back
方法将对象复制或移动到其目标位置。
顺便说一句,据我所知,大多数(如果不是全部)标准容器要求它们包含的对象是 copy-constructible 或 move-constructible。您的工会,如此处问题中所述,不是。
引用来源:Union declaration
没有干净的方法来做到这一点,原因很简单,给定这个 union
的任意实例,没有通用的权威方法,template-based function/method,比如std::vector::push_back
知道联合体的哪个成员是活跃的,以便执行 member-specific copy/move 操作,当联合体中至少有一个成员不是 POD 时。声明“此特定联合包含 std::string
因此要 copy/move 您将使用 std::string
的适当 copy/move 运算符”的联合的任何特定实例都没有固有的内容。 C++ 根本无法以这种方式工作,这是 C++ 的基础。没有解决方法,也没有语法。
一般来说,由于 C++ 在 type-safety 中的基础,当与 non-POD 成员如 std::string
一起使用时,固有的 type-unsafe union
会产生功能非常有限的最终结果。
对您来说最不痛苦的是用 C++17 的 std::variant
替换 union
,一个 type-safe 联合。 push_back
然后变成大胖子nothing-burger。
我有一个联合,定义如下:
union CellType {
std::string str;
int i;
double d;
Money<2> m; // Custom class for fixed-decimal math.
};
然后,我有一个这样的联合向量。
std::vector<CellType> csvLine;
我的问题是,如何将一个值附加到向量的末尾?我通常将 push_back
用于 vector
的字符串、整数等,但是当向量元素是并集时,我无法完全弄清楚语法。任何帮助将不胜感激。
(是的,这个 class 一次读取一行 CSV 文件,如果这有什么不同的话。)
这是失败的 MRE
#include <vector>
#include <iostream>
union CellType {
std::string str;
int i;
double d;
// Money<2> m; // Custom class for fixed-decimal math.
};
int main() {
std::vector<CellType> csvLine;
CellType c;
c.str = "foo";
csvLine.push_back(c);
}
Money 被注释掉了,因为与 MRE 无关
错误
Severity Code Description Project File Line Suppression State Error C2280 'CellType::CellType(void)': attempting to reference a deleted function ConsoleApplication1 C:\work\ConsoleApplication1\ConsoleApplication1.cpp 22
如果您使用的是 C++11 之前的编译器,那么:
Unions cannot contain a non-static data member with a non-trivial special member function (copy constructor, copy-assignment operator, or destructor).
和std::string具有non-trivial以上所有功能。
如果您使用的是支持 C++11 的编译器:
If a union contains a non-static data member with a non-trivial special member function (copy/move constructor, copy/move assignment, or destructor), that function is deleted by default in the union and needs to be defined explicitly by the programmer.
If a union contains a non-static data member with a non-trivial default constructor, the default constructor of the union is deleted by default unless a variant member of the union has a default member initializer.
这基本上意味着您没有任何联合构造函数,您需要自己定义复制或移动构造函数才能使以下行起作用:
csvLine.push_back(c);
as push_back
方法将对象复制或移动到其目标位置。
顺便说一句,据我所知,大多数(如果不是全部)标准容器要求它们包含的对象是 copy-constructible 或 move-constructible。您的工会,如此处问题中所述,不是。
引用来源:Union declaration
没有干净的方法来做到这一点,原因很简单,给定这个 union
的任意实例,没有通用的权威方法,template-based function/method,比如std::vector::push_back
知道联合体的哪个成员是活跃的,以便执行 member-specific copy/move 操作,当联合体中至少有一个成员不是 POD 时。声明“此特定联合包含 std::string
因此要 copy/move 您将使用 std::string
的适当 copy/move 运算符”的联合的任何特定实例都没有固有的内容。 C++ 根本无法以这种方式工作,这是 C++ 的基础。没有解决方法,也没有语法。
一般来说,由于 C++ 在 type-safety 中的基础,当与 non-POD 成员如 std::string
一起使用时,固有的 type-unsafe union
会产生功能非常有限的最终结果。
对您来说最不痛苦的是用 C++17 的 std::variant
替换 union
,一个 type-safe 联合。 push_back
然后变成大胖子nothing-burger。