gpt4 book ai didi

相当于Rust枚举的C++

转载 作者:行者123 更新时间:2023-12-03 06:51:28 24 4
gpt4 key购买 nike

这个例子展示了一种优雅的方式来处理Rust中不同类型的消息。它具有4个变体,并且某些变体具有子成员,只有在枚举属于该特定类型时,该子成员才可以访问。在TypeScript中也可以使用类似的模式。

enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
在C++中,这很可能会与以下代码进行比较。
struct Message
{
enum MessageType {QUIT, MOVE, WRITE, CHANGECOLOR} type;
union MessageContent
{
struct Move { int x; int y;} move;
std::string write;
std::tuple<int, int, int> changeColor;
} content;
};
但是,这种方式不是类型安全的,并且内存管理将变得困惑(例如,如果 MessageMessageType,则如果 WRITE被破坏了,则确保释放字符串)。在现代C++中执行此操作的最佳方法是什么?

最佳答案

这就是 std::variant 的用途。
(请注意,由于C++没有模式匹配,与Rust之类的语言相比,使用变体仍然很麻烦。)
使用std::variant,您的示例将类似于this:

struct Quit {};
struct Move { int32_t x; int32_t y; };
struct Write { std::string s; };
struct ChangeColor { int32_t r; int32_t g; int32_t b; };
using Message = std::variant<Quit, Move, Write, ChangeColor>;
与Rust的 match表达式最接近的是 std::visit 。访问此示例变体可能如下所示:
// Utility to allow overloading lambdas for use in std::visit
template<class... Ts>
struct overload : Ts... {
using Ts::operator()...;
};
template<class... Ts>
overload(Ts...) -> overload<Ts...>;

int main() {
auto visitor = overload{
[](const Quit& q) { std::cout << "Quit\n"; },
[](const Move& m) { std::cout << "Move " << m.x << " " << m.y << "\n"; },
[](const Write& w) { std::cout << "Write " << w.s << "\n"; },
[](const ChangeColor& c) { std::cout << "ChangeColor " << c.r << " " << c.g << " " << c.b << "\n"; }
};

Message m1{Quit{}};
Message m2{Move{1, 2}};
Message m3{Write{"a"}};
Message m4{ChangeColor{1, 2, 3}};
std::visit(visitor, m1);
std::visit(visitor, m2);
std::visit(visitor, m3);
std::visit(visitor, m4);
}
// This prints:
// Quit
// Move 1 2
// Write a
// ChangeColor 1 2 3

关于相当于Rust枚举的C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64017982/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com