2

the code below prints val2 on both f() calls. What would be a proper way to execute specific branch in f() based on enum value ?

enum class E
{
    val1,
    val2
};

using val1_t = std::integral_constant<E, E::val1>;
using val2_t = std::integral_constant<E, E::val2>;
    

template <typename T>
void f(T t)
{
    if constexpr (std::is_same_v<T, val1_t>)
    {
        std::cerr << "val1\n";
    }
    else
    {
        std::cerr << "val2\n";
    }
}


int main()
{
    f(E::val1);
    f(E::val2);
}
psb
  • 342
  • 3
  • 12

1 Answers1

9

If you move the enum into the template parameter, then you could use

template <E val>
void f()
{
    if constexpr (val == E::val1)
    {
        std::cerr << "val1\n";
    }
    else
    {
        std::cerr << "val2\n";
    }
}

And you would use it like

int main()
{
    f<E::val1>();
    f<E::val2>();
}
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • Thank you. So there is no way to somehow infer std::integral_constant-generated-type from passed enum value ? Maybe not with std::is_same_v, but somehow else ? I would still like to have something like `f(E::val1)` at call site. – psb Sep 13 '21 at 18:13
  • @psb You could do something like [this](http://coliru.stacked-crooked.com/a/283b6d2daa3a3d6f) – NathanOliver Sep 13 '21 at 18:16
  • @psb The issue with function parameters is they are never compile time constants. That means you can't use them where a compile time constant is required. – NathanOliver Sep 13 '21 at 18:17
  • 1
    @psb That first example was a little to complicated. Here is a reduced version: http://coliru.stacked-crooked.com/a/c6ba1f71a2d9f76f – NathanOliver Sep 13 '21 at 18:22
  • Yeah, I more or less understand that, but I've been thinking that since all enum values are known at compile time, there may be a way to deduce a type, based on enum value, from enum value at compile time. – psb Sep 13 '21 at 18:23
  • So, I guess, I can substitute `enum` with something like this: `struct E { static inline struct Val1{} val1; static inline struct Val2{} val2; };` – psb Sep 13 '21 at 18:27
  • @psb You could do that. That technique is called tag dispatch. Basically, you use the types of the parameter instead of it's value to do something. – NathanOliver Sep 13 '21 at 18:32