gpt4 book ai didi

C++ 跟踪类内的变化

转载 作者:行者123 更新时间:2023-11-30 05:18:28 24 4
gpt4 key购买 nike

想象一个代表邮件的类:

class mail {
string subject;
string content;
date receivedDate;
};

现在我想要实现的是知道我的邮件数据是否已设置,一旦设置,哪些发生了变化。我可以像这样组合使用 std::optional 和 std::map :

class Mail {
std::optional<string> subject;
std::optional<string> content;
std::optional<date> receivedDate;

enum EField { Subject, Content, ReceivedDate };

typedef std::map<EField, bool> ChangedMap;

ChangedMap changedFields;

public:
Mail(optional<string> subject, ... ) {
// initialize map with fields... hard coded
}

bool HasSubject() const { return subject; }

string GetSubject() const { return subject.get(); }

void SetSubject(const std::string& newSubject) {
subject = newSubject;
changedFields[Subject] = true;
}

void RemoveSubject() {
changedFields[Subject] = HasSubject();
subject.reset();
}

bool IsSubjectChanged() const {
return changedFields[Subject];
}
};

但我真的认为我在这里遗漏了一些关键的东西。您是否会看到更好的方法来做到这一点,最好是使用更少的内存并且没有硬编码值?

我考虑过从 std::optional 继承,但我也不认为这是一件好事。

谢谢

最佳答案

让我们概括这个问题:给定一个类型 T , 我想要一个 wrapper tracked<T>在运行时跟踪读取/写入的历史记录。

我会使用 std::tuple 来解决这个问题和元编程。首先,让我们定义mailstd::tuple 方面:

class mail
{
private:
std::tuple<string, string, date> _data;

public:
// `variant_type` could be automatically computed from the
// tuple type.
using variant_type = std::variant<string, string, date>;

enum class index
{
subject = 0,
content = 1,
date = 2
};

template <index TIndex>
decltype(auto) access()
{
return std::get<static_cast<std::size_t>(TIndex)>(_data);
}
};

然后我会创建类似 tracked<T> 的东西跟踪在 T 上执行的操作:

template <typename T>
class tracked
{
private:
using index_type = typename T::index;
using variant_type = typename T::variant_type;

struct write_action
{
variant_type _before;
variant_type _after;
};

struct read_action
{
index_type _index;
};

T _data;
std::vector<std::variant<write_action, read_action>> _history;

public:
template <index TIndex>
const auto& read() const
{
_history.emplace_back(read_action{TIndex});
return _data.access<TIndex>();
}

template <index TIndex, typename T>
void write(T&& new_value) const
{
// Remember previous value.
variant_type _before{_data.access<TIndex>()};

_history.emplace_back(write_action{_before, new_value});
return _data.access<TIndex>() = std::forward<T>(new_value);
}
};

上面的代码并不完全正确,因为您需要action 类型的构造函数、异常处理、移动语义支持等等。不过,我希望您能了解总体思路。

关于C++ 跟踪类内的变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41693548/

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