【发布时间】:2017-12-06 00:54:03
【问题描述】:
能否在编译时检测“函数参数”1 是否为编译时常量?
例如一个函数print(int i),如果调用为print(5),则可以打印"constant 5",但如果调用为print(i),则"non-constant 5",其中i是一些非常量变量。特别是,在“恒定”分支中,我应该能够将 i 视为 constexpr,包括将其用于模板参数等。
宏技巧、模板元编程和 SFINAE 技巧都可以。理想情况下,它是可移植的,但特定于编译器的解决方案总比没有好。
如果存在“假阴性”也没关系 - 即,如果常量值有时被检测为非常量(例如,当某些优化被禁用时)。
如果解决方案可以检测到常量值何时间接传递给函数(例如,当常量值传递给调用print 并且随后内联将常量暴露给print 的中间函数时),则加分.最后一种行为显然取决于优化。
如果自然扩展到多个参数,则加倍加分。
如果可以有带和不带constexpr 参数的函数的重载版本,这可能很简单,但是you can't。
1 我在这里将“函数参数”放在引号中,因为该解决方案并不严格要求在函数内(或在调用者/被调用者边界使用特殊参数检测此状态) - 它只需像函数一样出现在调用者面前,但可以使用宏或其他技巧,例如带有 operator() 等的静态对象。
【问题讨论】:
-
我记得 GCC 有类似
__builtin_constant_p的东西。但是,使用宏,我确信有更多可移植的方式,但该宏肯定必须面向用户。 -
可以在此处检测到 constexpr:stackoverflow.com/a/15236647/1294207 也许可以提供帮助?
-
顺便说一句,您说“简单地”使用 constexpr 参数重载,但实际上并非如此。在提出标准化建议时,这引发了巨大的讨论。
-
@max66 - 对,但它不必是一个普通函数
void print(int i)- 它可以是一个类似函数的宏,它可以在其参数上发挥一些魔力,并根据具体情况调用不同的函数无论是常数,还是某种模板魔法。我只是说代码的用户应该编写类似print(5)的东西,并且在内部我希望能够采用constexpr代码路径,具体取决于参数是否可以用作constexpr。 -
您可以使用参数计数宏技巧的变体将宏解决方案扩展到多个参数(请参阅:stackoverflow.com/q/11317474/315052),因此您可以定义
Print1、Print2,...等, 然后Print(...)将根据参数计数宏的结果调用正确的PrintN宏。
标签: c++ c++11 optimization constexpr