Search code examples
c++c++11constexprstatic-assert

How to use static_assert inside of a constexpr


I have a function that can be called on an enum, save for one value. I want to check statically that the function is not called with that value. I have the following (simplified) (c++11) code:

enum class Channel: char {
    ALL = 0,
    ONE = 1,
    TWO = 2,
};

inline constexpr std::size_t zeroBasedChannelIndex(const Channel channel) {
    static_assert(channel != Channel::ALL, "Channel::All doesn't map to an index");
               // ^^^^^^^ error location
    return static_cast<std::size_t>(channel) - 1;
}

I'm getting the following error though: the value of parameter "channel" (declared at line 16 of "/opt/kvanwel/Workspaces/acdipole/amplib/src/powersoft/kseries/datamodel/../constants/Channel.h") cannot be used as a constant

It looks to me that channel IS constant... but computer says no. What am I doing wrong here?


Solution

  • The comments above have told you what's wrong. The only thing you can do to get round this is to pass channel as a template parameter:

    template <Channel channel> constexpr std::size_t zeroBasedChannelIndex () {
        static_assert(channel != Channel::ALL, "Channel::All doesn't map to an index");
        return static_cast<std::size_t>(channel) - 1;
    }
    

    But now, that parameter must be known at compile time (i.e., in practise, a constant, most likely) when calling the function.