Search code examples
c++templatesconstexprconstant-expression

take template basis on run-time value


I have an enum:

enum operation {
 plus,
 delete
 //...
}

There is function, which has a run-time argument.

operation_do(plus);

And inside that function, there is a template-function call, which is based on a run-time argument. Important: I can NOT make operation_do(), as a template function. This is the condition.

void operation_do(operation op) {
    call<op>();
}

I have a compiled error: op is not a constant expression.

I tried to resolve this with the help function, like this:

constexpr operation get(operation arg) {
    return arg;
}

void operation_do(operation op) {
    constexpr operation elem = get(op);
    call<elem >();
}

But it is still the same error: op is not a constant expression. Can anyone help, please, with this?


Solution

  • And inside that function, there is a template-function call, which is based on a real-time argument. Important: I can NOT make operation_do(), as a template function. This is the condition.

    This is the problem.

    In C++ a run-time value (so a function argument, that can be a run-time value) can't be used as template parameter.

    For the same reason can't works the passage through a constexpr value

    void operation_do(operation op) {
        constexpr operation elem = get(op); // <--- error
        call<elem >();
    }
    

    because elem can't be initialized from a run-time value.

    The best I can imagine is the use of a sequence of if (or, maybe better, a switch) to pass from a run-time value to a compile-time value.

    Something as

    void operation_do (operation op)
     {
       switch ( op )
        { 
          case plus:
             call<plus>();
             break;
    
          case del:
             case<del>()
             break;
        }
     }
    

    Obviously this is acceptable only if the number of the enum value is limited and if you can concentrate the switch in a single place.

    Note that delete is a keyword, so you can't use it as an identifier.