c – 避免多个模板实例化函数的优雅方法,不依赖于模板化类型
发布时间:2020-12-16 09:53:41 所属栏目:百科 来源:网络整理
导读:我有一个基本类看起来像这样: template typename TCode,TCode SuccessValclass Error{public: typedef TCode code_t; Error(TCode code,char const *descr="Unknown Error."): code(code),descr(descr) { } ... char const *description() const { return d
我有一个基本类看起来像这样:
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: %sn",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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |