如何在C++中创建事务流
How do you create a transactional stream in C++?
我需要在C++中创建"事务流"。我所说的"事务流"是指如果在处理过程中出现错误,就会倒带的流。例如如果流的使用者以某种方式无法处理流的数据,我希望在生成数据之前将流恢复到其状态。
也许一条懒惰的溪流就能做到这一点?这是一种常见的情况和常见的解决方案吗?还是我一定要为我的特定问题编写自己的自定义实现?
首先想到的是将范围接口(用于惰性和可组合性)与事务接口(用于回溯)相结合:
#include <iostream>
#include <stack>
#include <sstream>
struct transaction_failure {};
class transactional_istream_range {
std::istream& stream;
std::stack<std::streampos> states;
public:
transactional_istream_range(std::istream& stream)
: stream(stream) {}
// Transaction interface.
template<class R, class T>
R transaction(R(*body)(T&)) {
try {
begin();
R result = body(*this);
commit();
return result;
} catch (const transaction_failure&) {
rollback();
}
return R();
}
void begin() {
states.push(stream.tellg());
}
void commit() {
states.pop();
}
void rollback() {
stream.seekg(states.top());
states.pop();
}
// Range interface.
bool empty() const {
return stream.peek() == EOF && stream.eof();
}
char front() const {
return stream.peek();
}
void pop_front() const {
stream.ignore(1);
}
};
然后,您可以轻松地编写在事务范围上操作的模板函数:
#include <cctype>
template<class R>
std::string parse_integer(R& input) {
std::string result;
while (!input.empty()) {
if (std::isdigit(input.front())) {
result += input.front();
input.pop_front();
} else {
throw transaction_failure();
}
}
return result;
}
int main() {
std::istringstream stream("1234a");
typedef transactional_istream_range tir;
tir input(stream);
std::string result = input.transaction(parse_integer<tir>);
std::cout << "Result: " << result;
}
这只是第一个近似值;您可能不必指定事务函数的范围类型(即,仅指定parse_integer
而不是parse_integer<...>
)。以范围形式编写许多类型的惰性流和惰性算法是非常简单的
至于扩展它,您可以将事务处理参数化,以调用用户指定的提交或回滚函数,或者只单独实现每种类型的回滚。使用mixin将范围接口与事务接口解耦也可能是有益的。不过,如果不使用虚拟功能,我现在想不出一个好的方法。
如果你在Windows上工作,有一种叫做结构化存储的东西可以提供一种交易形式。你可能不得不把你的问题分解成不同的问题。
以下是更多信息:http://msdn.microsoft.com/en-us/library/windows/desktop/aa380369(v=vs.85).aspx
或者,您可以考虑使用类似SQLite或Firebird的东西来提供后端事务存储。
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 使用std::multimap迭代器创建std::list
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 使用CMake创建QML插件
- 如何在c++中为模板函数实例创建快捷方式
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- OpenCV EqualizeHist()从彩色图像创建黑白图像
- 试图在visual studio上用C++创建一个桌面应用程序
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 如何在C++20中创建模板别名的推导指南
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 如何创建一个空的全局类并在启动时实例化它
- 无法创建抽象类的实例
- 链接到自行创建的dll失败
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何在C++类内存结构中创建"spacer"?
- 终端不会为C++文件创建.exe文件吗
- 如何在C++中创建事务流