Reputation: 4493
NB: This if purely for self-education.
I have following template:
template <typename T, T val>
void Foo() {
static_assert(false, "You should not be here");
}
and I want to create many specializations, like this:
enum class ENUM { A, B };
template<>
void Foo<ENUM, ENUM::A>() {
// something
}
This code works correctly with ENUM::A as template argument, and correctly triggering static_assert, when called not with ENUM::A.
The question is - call syntax for such functions is very ugly, like this:
Foo<ENUM, ENUM::A>();
Is there any way to shorten it for just
Foo<ENUM::A>();
But, leaving intact the idea, that other enum-types can be passed as template parameter.
Code below is NOT a solution
template <ENUM val>
void Foo() {} // and further specialize only for values of ENUM
Upvotes: 2
Views: 168
Reputation: 76391
Can't think of a way to do it exactly as you want.
However, if you're willing to invest some effort (in a way which can be mitigated, moreover - below) in order to make the various versions easy to call, you could use std::integral_constant
to make things into types;
#include <iostream>
#include <type_traits>
using namespace std;
enum class ENUM{ A, B };
using AT = integral_constant<ENUM, ENUM::A>;
using BT = integral_constant<ENUM, ENUM::B>;
template<typename T>
void Foo();
template<>
void Foo<AT>()
{
cout << "a" << endl;
}
int main ()
{
Foo<AT>();
return 0;
}
Why is this better than before?
You might think it's not!
If you're planning on writing a lot of code calling these functions, it might be a saving.
It's quite easy to write a macro to automate those using
s at the top.
Upvotes: 1