【发布时间】:2020-02-26 08:50:39
【问题描述】:
我正在尝试通过使用枚举类作为模板参数在编译时优化某些函数。
举个例子
enum class Color { RED, BLACK };
现在,我想定义一个方法
void myMethod<Color c> () {
if( c == Color::RED ) { ... }
if( c == Color::BLACK ) { ... }
}
并且我希望编译器制作 2 个 myMethod 的副本并在优化期间消除死代码(它适用于 CUDA 内核,因此速度和寄存器的使用对我来说很重要)
但是,似乎当我使用
调用该方法时void doSomething( const Color c ) {
myMethod<c>();
}
MSVC 抱怨“表达式必须有一个常量值”。
我期待编译器足够聪明,可以用每个可能的枚举版本编译 myMethod 的版本。不是这样吗?我可以强制它在 doSomething 中没有丑陋的开关吗?
感谢您的帮助!
【问题讨论】:
-
如果它依赖于非常量变量,您必须在运行时决定要调用哪个
myMethod<Color>()。所以,你又回到了switch()(或 if-else-cascade,或将颜色映射到函数指针的数组,或其他)。 -
这似乎最近经常发生。
const不会生成(编译时)常量表达式,即可以在编译时计算的表达式。 -
简而言之:模板=编译时,普通函数参数=运行时。你可以混音,但是你需要定义如何混音,例如已经提到的用一个开关来选择调用哪个函数
-
很公平,但与 const 表达式无关,我仍然认为编译器会以某种方式读出我的枚举并在运行时根据参数的值做出决定。好吧,也许我期望太高了......谢谢你的帮助:)
-
您可能想要实现的目标,我曾经申请一个有趣的项目,将
ifs 从最内部的循环移到外部。当然,必须为每种情况重新实现嵌套循环。在那里,我使用了带有值的模板参数来防止代码重复。 the template,call of that template 和一点解释Optimization Attempts。