【问题标题】:Compile time checking of constness编译时检查常量
【发布时间】:2014-09-03 15:25:55
【问题描述】:

如果我有一个功能

int calcStuff_dynamic(const int a, const int b)

还有一些模板元代码

template<int a, int b>
struct calcStuff_static {
    static const int value = //some more code
};

有没有办法写一个包装器

int calcStuff(const int a, const int b) {
    IF_THESE_ARE_KNOWN_CONSTANTS_AT_COMPILE_TIME(a, b)
        return calcStuff_static<a, b>::value;
    ELSE_TEMPLATE_WOULD_FAIL
        return calcStuff_dynamic(a, b);
}

【问题讨论】:

  • “IF_THESE_ARE_KNOWN”是什么意思?
  • 您在静态情况下使用的算法是否与在非静态情况下不同?为什么?否则,您正在寻找constexpr
  • constexpr
  • acalcStuff 中的b 不是常量表达式,因此它们不能用作calcStuff_dynamic 中的模板参数。
  • gcc 4.3 太​​旧了,当你给它无意义的编译标志时,它甚至不会出错:-)

标签: c++ templates template-meta-programming compile-time compile-time-constant


【解决方案1】:

你不能这样做,但它会由智能编译器完成。

也许想到的第一个解决方案是将 SFINAEconstexpr 值结合使用。在这种情况下,我们需要一些东西来检测 constexpr 值。

但是,没有is_constexpr 或类似的东西来检测编译时已知的值。另一方面,函数is_const 没有用处,因为constexpr 不是类型的一部分。所以,你不能这样做(或者至少我不知道一个直接的解决方案)。

但是,如果您知道有许多编译器可以在编译时为已知值计算函数的最终值,那么您会很高兴。例如在 GCC 中,有 “SCEV 终值替换”

因此,您应该只在参数未知时使用该动态函数,编译器会按照您的意愿执行(如果可能的话)。

【讨论】:

  • 太酷了。 SCEV 是否对元编程的某些用途没有实际意义?
  • 当我在 avr-g++-4.3 上查看 gcd(3432,gcd(231,2312)) 的程序集时,我发现它没有展开。这是 g++ 的新特性吗?
【解决方案2】:

GCC、Clang 和 Intel 编译器都支持 __builtin_constant_p 来检查该值是否为编译时常量并在这种情况下提供优化的表达式。

对于所有其他编译器,您可以使用动态计算作为备用。 (我不知道 Visual Studio 是否有等价物。)

【讨论】:

  • 谢谢。在这种情况下它实际上不起作用:int calcStuff(const int a, const in b) { return __builtin_constant_p(a) &amp;&amp; __builtin_constant_p(b) ? calcStuff_static&lt;a,b&gt;::value : calcStuff_dynamic(a,b); }
  • @user315118 将a &amp;&amp; b ? expr1 : expr2 表示为a ? (b ? expr1 : expr2) : expr2 是否有效?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-19
  • 2015-12-04
  • 1970-01-01
  • 1970-01-01
  • 2018-11-13
  • 2012-08-07
  • 1970-01-01
相关资源
最近更新 更多