我正在试验复杂的FSM框架。对于我正在考虑的一种方法,我想要有两种类型的函数:普通函数和特殊函数。确切的意思并不重要。我希望编译时强制执行,每个块不超过一个特殊功能。我可以使用函数类型(例如,对返回值进行特殊操作)、签名、属性、模板元编程、包装宏、函数对象等。
每个块非常简单,只是几个函数调用的简单序列:
{
funcA();
funcB();
..
funcC();
}
发布于 2017-04-24 15:52:10
我不认为你能舒服地做这件事。您正在尝试在C++之上实现您自己的语言,但是C++并不真正具有这种可扩展性。
其次是流畅的界面。通过一个流畅的界面,我们可以将我们设计的语法编码到类型系统中。我们不能强制每个C++块只调用一个特殊函数,但我们可以强制只调用级联中的一个特殊方法。例如:
// Mixin for end() operation
struct can_end {
auto end() && -> void {}
};
// Mixin for normal methods
template<typename next_state>
struct can_normal {
auto normal_1() && -> next_state { return {}; }
auto normal_2() && -> next_state { return {}; }
};
// State after special method: only end and normal methods allowed
struct after_special : can_end, can_normal<after_special> {
after_special() = default;
after_special(after_special const&) = delete;
};
// State before special method: end, normal, and special allowed
struct before_special : can_end, can_normal<before_special> {
before_special() = default;
before_special(before_special const&) = delete;
auto special() && -> after_special { return {}; }
};
// Entry point
auto block() -> before_special { return {}; }
现在,我们可以编写一个方法级联,如:
block()
.normal_1()
.special()
.normal_2()
.end();
但将被阻止两次调用该特殊方法:
block()
.special()
.special() // type error
.end();
通过删除复制ctor,我们防止使用临时变量捕获预特殊状态:
auto temp = block(); // compilation error: deleted copy ctor
temp.special();
temp.special().end();
由于所有方法都接受rvalue引用,这也会阻止欺骗,比如将状态绑定到引用,然后调用两次特殊方法。但我相信C++型系统有足够的逃生舱口,如果你真的下定决心的话。
发布于 2017-05-04 18:05:02
也许我忽略了一些东西,但考虑到您对块的严格要求,以下几点就足够了:
#define specialFunction(...) \
int SPECIAL_FUNCTION_ALREADY_CALLED = 0; \
specialFunction(__VA_ARGS__)
在同一个块中尝试两次调用specialFunction
将重新定义变量,从而触发编译时错误。
main.cpp:6:9: error: redeclaration of 'int SPECIAL_FUNCTION_ALREADY_CALLED'
int SPECIAL_FUNCTION_ALREADY_CALLED = 0; \
^
警告:不跨嵌套块工作,中断函数调用作为表达式的所有使用。但这似乎符合要求。
https://softwareengineering.stackexchange.com/questions/347686
复制相似问题