【问题标题】:print static variable for template metaprogramming打印模板元编程的静态变量
【发布时间】:2016-04-24 00:17:09
【问题描述】:

我有以下template metaprogramming 的阶乘实现:

#include <iostream>

template <int n> struct factorial{
  static const int res = n*factorial<n-1>::res;
};

template <> struct factorial<0>{
  static const int res = 1;
};

int main(){
  std::cout << factorial<5>::res << '\n';
  return 0;
}

此代码编译成功并按预期输出 120。但是,纯粹出于自娱自乐的原因,我想改为让它编译,而是在编译器的错误消息中显示120。

是否有一个简单的语法错误,我可以故意输入我的代码使其无法编译,但仍会在编译器错误消息中打印 5!,即 120?

我预计答案可能取决于编译器;我目前正在使用 Xcode Mac OSX 附带的 g++,iirc 是 clang 的前端。

【问题讨论】:

  • 如果你允许-Werror,就可以了。 coliru.stacked-crooked.com/a/34dfcdcb110e9bc4 static_assert 如果这不是作弊,可能会有所帮助。
  • @BaummitAugen: ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
  • @LightnessRacesinOrbit 好吧,我想在this comment 之后,我无法完全摆脱“可能对 OP 没有用”。 :)

标签: c++ compiler-errors template-meta-programming static-variables


【解决方案1】:

您可以使用已声明但未定义的模板将值打印为编译时错误。

template<int n>
class display;

template<int n> struct factorial{
    static const int res = n*factorial<n-1>::res;
};

template<> struct factorial<0>{
    static const int res = 1;
};

int main()
{
    display<factorial<5>::res> value;
}

g++ 输出:

g++ -std=c++11 fact.cxx
fact.cxx: In function ‘int main()’:
fact.cxx:14:29: error: aggregate ‘display<120> value’ has incomplete type and cannot be defined
  display<factorial<5>::res> value;
                             ^

【讨论】:

    【解决方案2】:

    如果选项 -Werror 被允许,或者如果警告算作错误,则:

    #include <iostream>
    
    template <int n> struct factorial{
      static const int res = n*factorial<n-1>::res;
    };
    
    template <> struct factorial<0>{
      static const int res = 1;
    };
    
    int main(){
      char x[factorial<5>::res];
      return x[sizeof(x)];
    }
    

    会产生错误/警告

    错误:“x[120ul]”在此函数中未初始化 [-Werror=uninitialized]

    使用 gcc 5.3 或

    错误:数组索引 120 超出了数组的末尾(包含 120 个元素)[-Werror,-Warray-bounds]

    使用 clang 3.8。

    【讨论】:

    • 这非常适合显示整数。我认为为了显示双精度(即用于模板元编程计算 pi 或其他内容),我可以执行类似“static char c = x”之类的操作,如果 x 不是整数,则会打印警告
    • @xdavidliu 我不知道如何为doubles 做这件事,我会去睡觉知道的。您可以将其作为后续问题发布,如果没有人回答,请随时通过链接 ping 我,我明天会考虑。您的想法可能只包括类型,而不是值,但您自己看看。
    猜你喜欢
    • 2010-12-05
    • 2020-03-17
    • 1970-01-01
    • 2019-05-10
    • 2015-08-30
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多