Using c ++ std :: enable_if with normal function?

let's say I have an enumeration:

typedef enum {
  Val1,
  Val2,
  Val3,
  Val4
} vals;

And a function check(vals x)that returns a boolean value indicating whether val is in a specific subset of values ​​in vals.

bool check(vals x) {
  switch(x) {
  case Val1:
  case Val3:
    return true;
  }
  return false;
}

I want to use this function as a condition for enable_if(a function, as you can see, is not a function that depends on runtime) so that users can use only those values ​​with the class template.

class MyClass<vals v> {

}

PS: I need a template for specialization for a class method, depending on the value of the template.

+4
source share
3 answers

For this, you do not need either a function or enable_if.
Here is an example:

enum class vals {
    Val1,
    Val2,
    Val3,
    Val4
};

template<vals v, bool = (v == vals::Val1 || v == vals::Val3)>
class MyClass;

template<vals v>
class MyClass<v, true> { };

int main() {
    MyClass<vals::Val1> ok;
    // MyClass<vals::Val2> ko;
}

: MyClass<vals::Val2, true> ok; - .
, , .

enable_if, :

#include<type_traits>

enum class vals {
    Val1,
    Val2,
    Val3,
    Val4
};

template<vals v, std::enable_if_t<(v == vals::Val1 || v == vals::Val3)>* = nullptr>
class MyClass { };

int main() {
    MyClass<vals::Val1> ok;
    // MyClass<vals::Val2> ko;
}

static_assert:

enum class vals {
    Val1,
    Val2,
    Val3,
    Val4
};

template<vals v>
class MyClass {
    static_assert((v == vals::Val1 || v == vals::Val3), "!");
};

int main() {
    MyClass<vals::Val1> ok;
    // MyClass<vals::Val2> ko;
}

, , constexpr ed.

constexpr, @n.m. .

+4

++ 14 constexpr .

C + 11 return:

constexpr bool check(vals x) {
    return x == Val1 || x == Val3;
}
+6

Thanks for the answer guys. I found another solution that might be even better for my problem. Since I have to implement a specialized method for all supported values, I can even put the statement in a non-specialized method.

template<vals v>
MyClass<v>::method() {
  assert(check(v) && "Unsupported value!");
}

template<>
MyClass<Val1>::method() {
   // do it!
}
0
source

All Articles