加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读