Starl1ght
Starl1ght

Reputation: 4493

Shortening template function call with enum class as template parameter

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

Answers (1)

Ami Tavory
Ami Tavory

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?

  1. You might think it's not!

  2. If you're planning on writing a lot of code calling these functions, it might be a saving.

  3. It's quite easy to write a macro to automate those usings at the top.

Upvotes: 1

Related Questions