c++ - C++ 枚举类作为可变模板参数
问题描述
我试图通过使用枚举类作为模板参数在编译时优化一些函数。
比如说
enum class Color { RED, BLACK };
现在,我想定义一个方法
void myMethod<Color c> () {
if( c == Color::RED ) { ... }
if( c == Color::BLACK ) { ... }
}
而且我希望编译器myMethod
在优化期间制作 2 个副本并消除死代码(它适用于 CUDA 内核,因此速度和寄存器的使用对我来说很重要)
但是,似乎当我使用
void doSomething( const Color c ) {
myMethod<c>();
}
MSVC 抱怨“表达式必须有一个常量值”。我期望编译器足够聪明,可以myMethod
用枚举的每个可能版本编译一个版本。不是这样吗?我可以在没有丑陋的开关的情况下强制它doSomething
吗?
谢谢你的帮助 !
解决方案
您必须决定运行时 vc 编译时。编译时版本可以是这样的:
enum class Color { RED, BLACK };
template < Color c>
void myMethod () {
if constexpr ( c == Color::RED ) { std::cout << "RED" << std::endl; }
if constexpr ( c == Color::BLACK ) { std::cout << "BLACK" << std::endl; }
}
int main()
{
myMethod<Color::RED>( );
myMethod<Color::BLACK>( );
}
但是如果你想在运行时切换到编译时生成的特化,你必须切换所有可能的值:
enum class Color { RED, BLACK };
template < Color c>
void myMethod () {
if constexpr ( c == Color::RED ) { std::cout << "RED" << std::endl; }
if constexpr ( c == Color::BLACK ) { std::cout << "BLACK" << std::endl; }
}
void RuntimeDispatch( Color c )
{
if ( c == Color::RED ) { myMethod<Color::RED>(); }
if ( c == Color::BLACK ) { myMethod<Color::BLACK>(); }
}
int main()
{
RuntimeDispatch( Color::RED );
RuntimeDispatch( Color::BLACK );
}
根本没有办法将运行时变量用作模板参数,因为它根本不是编译时常量。
如果您必须使用较旧的编译器,则可以constexpr if
用模板专业化替换:
template < Color c> void myMethod ();
template <> void myMethod< Color::RED >() { std::cout << "RED" << std::endl; }
template <> void myMethod< Color::BLACK >() { std::cout << "BLACK" << std::endl; }
推荐阅读
- php - 如何获取 PHP DI 容器?
- javascript - 在单击按钮后等待打开 url
- android - 应用 APK 上传到 android 商店的大小是否有任何限制?
- maven - 我无法在我的机器中设置环境变量
- variables - 调用时未找到在表中使用表作为变量名
- python - 带有输入预处理的 TensorFlow NN 设计中的问题
- javascript - 如何在窗口加载和调整大小时将 innerHeight 用于 div?
- python - 如何生成用 flask-restplus 编写的现有 API 的机器可读 yaml 规范?
- django - 为什么 django 开发服务器的行为像单线程,而文档“默认情况下服务器是多线程的。”- 2.1 版
- python - 从 AWS 中的 Lambda 函数连接到 Oracle RDS