【问题标题】:How do I print a constant value at compile time?如何在编译时打印常量值?
【发布时间】:2018-12-21 15:30:48
【问题描述】:

使用模板元编程,TD trick 可用于在编译时将表达式的类型打印为错误消息。

这对于调试模板非常有用。是否有类似的方法来打印在编译时计算的

【问题讨论】:

    标签: c++ templates template-meta-programming


    【解决方案1】:

    是的,代码看起来非常相似:您声明(但未定义)一个template struct,其值作为模板参数。通过尝试在不定义它的情况下实例化它,你会得到一个编译器错误,说明常量值:

    template <int val>
    struct PrintConst;
    
    PrintConst<12*34> p;
    

    编译此代码时,g++ 失败并出现以下错误:

    const-display.cpp:4:19: error: aggregate ‘PrintConst<408> p’ has incomplete type and cannot be defined
     PrintConst<12*34> p;
                       ^
    

    请注意,它显示了表达式12*34,以及结果值408

    【讨论】:

    • 如何在不破坏编译的情况下做到这一点?
    • @SergeyA AFAIK,没有办法,除非你能以某种方式引起警告而不是错误。 (使用 -Werror 或等效的编译标志时可能仍会中断编译。)
    【解决方案2】:

    您也可以使用static_assert 来完成这项工作:

    template<int val>
    void static_print()
    {
        static_assert(val & false, "");
    }
    
    int main()
    {
        static_print<12*34>();
    }
    

    g++ 上的哪个输出:

    x.cc: In instantiation of ‘void static_print() [with int val = 408]’:
    x.cc:9:22:   required from here
    x.cc:4:20: error: static assertion failed
      static_assert(val & false, "");
    

    或在叮当声中:

    x.cc:9:2: note: in instantiation of function template specialization 'static_print<408>' requested here
        static_print<12*34>();
        ^
    

    【讨论】:

    • 我最初也考虑过使用 static_assert,但它只打印了表达式(就像在错误消息的最后一行中一样)。我喜欢在函数中使用它作为一种间接的想法!我不太确定接受哪个答案 - 你的看起来更好用,但我的写起来更短(如果它用作快速&肮脏的调试辅助工具并在之后再次从代码中删除,这可能会很方便)......跨度>
    • @anderas 作为更正,两条消息都显示了结果,但 gcc 没有显示原始表达式。无论如何,我认为您应该接受对您最有吸引力的那个,或者不接受任何人。我喜欢这个答案的原因是您可以将任何您想要的信息放在测试之外。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-08
    • 2012-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多