1

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?

Typhaon
  • 828
  • 8
  • 27
  • 2
    `static_assert` can't depend on function arguments it doesn't matter if function is a `constexpr`. `static_assert` is for time when function is compiled (or when template is instantiated), not when it is executed (even if it is executed during compile time - when compiling other function/code). – Marek R Dec 12 '22 at 09:39
  • It doesn't matter if `channel` is taken as a `const`. You can call the function with any `Channel` value. – Fareanor Dec 12 '22 at 09:41
  • Even when it's an inline constexpr? I thought inline meant that the code at the caller site was replaced with the code inside of the function... – Typhaon Dec 12 '22 at 09:43
  • 1
    @Typhaon no thats not what `inline` actually means. – 463035818_is_not_an_ai Dec 12 '22 at 09:48
  • https://stackoverflow.com/a/1759575/4117728 – 463035818_is_not_an_ai Dec 12 '22 at 10:04
  • Does this answer your question? [C++ run function at compilation time only](https://stackoverflow.com/questions/74597991/c-run-function-at-compilation-time-only) – Enlico Dec 12 '22 at 15:10

1 Answers1

3

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.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48