提问人:David Hovsepyan 提问时间:11/9/2023 最后编辑:HolyBlackCatDavid Hovsepyan 更新时间:11/9/2023 访问量:176
将枚举值转换为字符串
Convert enum values to strings
问:
我有以下代码片段:
enum class Code : uint8_t
{
A = 0,
B = 1,
C = 2
}
如何向枚举添加转换运算符(或类似的东西,如果可能的话),以便当我将枚举对象传递给接受的函数时,对象将被隐式转换为 。
目的是将字符串、等转换为字符串。std::string
std::string
0
"0"
1
"1"
注意:我不想添加这样的功能,例如, 因为我需要隐式转换。
toString
答:
2赞
mitch_
11/9/2023
#1
我最初发布了一个示例,说明如何使用一些隐式转换技巧来实现这一点,但意识到这可以进一步简化。
我假设你写了你想要将类型传递给的方法;然后,最简单的选择是添加一个简单的重载,该重载也接受 ,执行到 的转换,然后将结果传递给另一个方法,例如Code
Code
std::string
void work(std::string);
/* adding.... */
void work(Code c)
{
switch (c)
{
case Code::A: return work("A");
case Code::B: return work("B");
case Code::C: return work("C");
default: __builtin_unreachable();
}
}
如果该方法是标准库的一部分,我相信在这里添加您自己的重载将是 UB,但是您可以在新的命名空间中引入它并使用 ADL 来找出其余部分。
最好的答案最终将取决于你所处的确切情况,但这可能是一个很好的起点。
评论
4赞
Toby Speight
11/9/2023
而不是 ,通常最好将调用放在 之后,这样我们就不会丢失编译器检查是否考虑了所有值。default:
std::unreachable();
switch
0赞
kiner_shah
11/9/2023
@TobySpeight问题提到标记C++ 11,std::unreachable 来自C++ 23。
1赞
mitch_
11/9/2023
正确,但注释更多的是此处不应包含默认分支,并且调用应在交换机之外,以便更好地发出警告__builtin_unreachable
2赞
Toby Speight
11/9/2023
#2
我不确定你为什么需要这个,所以我的建议可能很宽泛。但是,如果你需要一个可以被视为 a 或字符串的值,那么我们可以创建一个包装类,它将转换为以下任一:Code
struct Code_class
{
Code c;
Code_class(Code c) : c{c} {}
operator Code() const
{
return c;
}
#define X(x) case Code::x: return #x
operator std::string() const
{
switch (c) {
X(A);
X(B);
X(C);
}
std::unreachable();
}
#undef X
};
完整演示
#include <cstdint>
#include <string>
#include <utility>
enum class Code : uint8_t
{
A = 0,
B = 1,
C = 2
};
struct Code_class
{
Code c;
/* implicit */ Code_class(Code c) : c{c} {}
operator Code() const
{
return c;
}
#define X(x) case Code::x: return #x
operator std::string() const
{
switch (c) {
X(A);
X(B);
X(C);
}
std::unreachable();
}
#undef X
};
#include <iostream>
int main()
{
auto m = Code::A;
Code_class p = m;
const std::string s = p;
std::cout << s << '\n';
}
评论
0赞
alagner
11/9/2023
我本着类似的精神写答案;)但后来我意识到样板代码可能会变得有点大,难以维护:来自枚举的额外赋值、比较等。
1赞
mitch_
11/9/2023
有趣的是,我们最初是如何聚集在相同的想法上的!这里的主要缺点是,执行此转换仍然需要一个显式步骤,因为原始类型不能传递给接受 a 的方法,而没有显式命名此处的构造函数,这相当于具有 OP 旨在避免的方法。Code
std::string
Code_class
toString
-1赞
Jakkapong Rattananen
11/9/2023
#3
char 是一种整数,因此我们可以声明 char 的枚举。
#include <iostream>
enum struct Cnum : char { h = 'h', o = 'o', e = 'e', l = 'l' , num_0 = '0' };
std::ostream& operator<<(std::ostream& os, Cnum c) {
os << static_cast<char>(c);
return os;
}
int main() {
std::cout << Cnum::h << Cnum::e << Cnum::l << Cnum::l << Cnum::o << Cnum::num_0 << "\n";//print hello0
}
然后你可以稍后从 char 构建字符串。
评论
1赞
mitch_
11/9/2023
我的假设是,OP 想要一个通用解决方案,该解决方案甚至适用于名称更复杂的成员。此外,枚举值的值可能需要为 0,但具有不同的字符串表示形式。
上一个:C++ 中的二维数组初始化11
下一个:C++ 向量声明语法
评论
FromEnum
static_cast<typename std::underlying_type<Enum>::type>(enumValue);
std::string
std::string