C++ enum class as a variable template parameter

 ̄綄美尐妖づ 提交于 2021-01-28 05:11:11

问题


I'm trying to optimize out some function at compile time by using an enum class as a template parameter.

Say for example

enum class Color { RED, BLACK };

Now, I would like to define a method

void myMethod<Color c> () {
 if( c == Color::RED ) { ... }
 if( c == Color::BLACK ) { ... }
}

And I would like the compiler to make 2 copies of myMethod and eliminate the dead code during the optimisation (it's for CUDA kernels so speed and register usage is important to me)

However, seems like when I call the method using

void doSomething( const Color c ) {
 myMethod<c>();
}

MSVC complains with "expression must have a constant value". I was expecting the compiler to be clever enough to compile a version of myMethod with each possible version of the enum. Is that not the case ? Can I force it to, without an ugly switch in doSomething ?

Thanks for your help !


回答1:


You have to decide for run-time vc compile-time. The compile time version can be something like that:

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>( );
}

But if you want in run-time switch to a compile-time generated specialization, you have to switch over all possible values:

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 );
}

There is simply no way to use a run time variable as a template parameter as it simply is never compile time constant.

if you have to use an older compiler, you can substitute the constexpr if with template specialization:

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; }


来源:https://stackoverflow.com/questions/60409984/c-enum-class-as-a-variable-template-parameter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!