template <typename TCode,TCode SuccessVal>class Error{public: typedef TCode code_t; Error(TCode code,char const *descr="UnkNown Error."): code(code),descr(descr) { } ... char const *description() const { return descr; } ...private: TCode code; char const *descr;};
它所做的就是封装某种错误代码枚举类,以便为日志记录提供更多的上下文.
现在说我有一个功能恐慌:
template <typename TCode,TCode SuccessVal>voID panic(Error<TCode,SuccessVal> const &e){ puts("Panic!"); printf("Unrecoverable error: %s",e.description()); abort();}
使用-fdump-tree-original进行编译表明,在我的情况下,这会导致一些不同的函数,使用完全相同的代码.这是你所期望的,但可能不是你想要的.
一个显而易见的路径是一个只有消息和构造函数接收消息的基类,但我发现它相当缺乏吸引力.
我们从不使用错误代码本身,所以我们所做的一切都取决于T.我如何避免大量模板实例化编译成基本相同的代码?
另一个理想的特性是确保无论TCode是什么类型,它都可以对整数类型进行强制转换.
解决方法 这段代码的一个明显因素是:[[noreturn]] voID panic_with_message(char const * msg){ std::printf("Panic!\nUnrecoverable error: %s\n",msg); std::fflush(stdout); std::abort();}template <typename T,T Val>[[noreturn]] static inline voID panic(Error<T,Val> e){ panic_with_message(e.description());}
您只能将模板放入标题中,并附上函数声明,并将函数定义保存在单独的转换单元中.这应该使代码膨胀到最低限度:
// panic.hpp#ifndef H_PANIC#define H_PANIC#include "error.hpp" // for Error<T,Val>[[noreturn]] voID panic_with_message(char const * msg);template <typename T,Val> e){ panic_with_message(e.description());}#endif总结
以上是内存溢出为你收集整理的c – 避免多个模板实例化函数的优雅方法,不依赖于模板化类型全部内容,希望文章能够帮你解决c – 避免多个模板实例化函数的优雅方法,不依赖于模板化类型所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)