如何解决使用C ++编译时间RAII类型的行为
| 我知道这听起来有些奇怪,但这就是我想要做的:假设我有一个函数void f()
,并且我想为此方法添加跟踪。我想通过跟踪消息(例如\“ Entered function f \”和\“ Exited function f \”)来跟踪此函数的完整性和该函数的退出。我不想为进入和退出添加手动跟踪条目,因为我可能会错过一些返回路径。因此可以在编译时使用模板魔术,并自动生成这些字符串。即我想要实现的是
void f()
{
some_template<magic>(\"f\");
}
这应该在构造函数中添加跟踪消息\“ Entered function f \”,在析构函数中添加\“ Exited function f \”。我要它编译时,并且不想创建任何运行时对象。在C ++中可能吗?任何可以在其中找到更多信息的指针(如果可以实现的话)?
解决方法
剩下的方法仅在运行时才知道,因为任何种类的异常都可能在代码的任何一点(通常来说)发生。因此,这里没有编译时解决方案。
, 您确实需要让调试器或编译器执行此工作。没有创建对象就无法使用RAII,此外,没有模板可以访问函数名称。
但是,如果您可以接受一个对象,那没什么大不了的。
class tracer {
std::string exit;
public:
tracer(std::string entry,std::string exit_)
: exit(exit_) {
std::cout << entry;
}
~tracer() { std::cout << exit; }
};
void f() {
tracer scope(\"Oh hai,I is entering f()\",\"Oh bai,I is leaving f()\");
}
, 无论如何,所有代码都是在编译时创建的,那么类有什么问题?编译器会将构造函数和析构函数调用放在它们所属的位置,这正是您想要的。调用这些函数的运行时成本很高,因为这是您的目标,因此这是完全不可避免的。
似乎保存\"f\"
会花费char const*
,但是任何体面的优化程序都会注意到,字符串文字是一个常量,不会在整个函数中更改,因此不需要存储它,但可以重新加载它。让优化器决定缓存指针是否有效。我无法预测。
, 如果您对此真的很认真,那么使用AspectC ++是一种选择。但是,这样做的门槛很高,而且我认为,如果您这样做,就会发现自己充斥着输出。更好的选择是使用调试器(设置打印某些输出的断点)或包装在类似DeadMG建议的类中的ol'printf / cout。 ___FILE___
和___LINE___
可能是此类的有用输入。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。