简体   繁体   中英

C++ Enum Template Functions: Compile Time Reflection

in principle the question is about the best way of getting reflexive iteration over an enum at compile time.

Let's assume I have an enum

enum Animal {
    DOG = 0,
    CAT = 12,
};

Now I have a function template

template <Animal A>
void animalVoice();

And I specialise the template:

template <>
void animalVoice<DOG>() {cout << "Bau" << endl;}
template <>
void animalVoice<CAT>() {cout << "Meow" << endl;}

Do I have the possibility of getting the same behaviour as in

int main() {
    animalVoice<DOG>;
    animalVoice<CAT>;
    return 0;
}

By iterating at compile time over the value of the enum?

Thanks

M.

You might have an animal container:

enum Animal {
    DOG = 0,
    CAT
};

constexpr auto all_animals = std::integer_sequence<Animal, DOG, CAT>{};

and then

template <Animal... Args>
void call_animalVoice()
{
    (animalVoice<Args>(), ...);
}

template <Animal... Args>
void call_animalVoice(integer_sequence<Animal, Args...>)
{
    // (animalVoice<Args>(), ...);
    call_animalVoice<Args...>();
}

with call:

call_animalVoice(all_animals)

or maybe std::tuple

constexpr auto all_animals = std::tuple<
    std::integral_constant<Animal, DOG>,
    std::integral_constant<Animal, CAT>
>{};

and

std::apply([](auto... animals){ (animalVoice<decltype(animals){}()>(), ...);
 }, all_animals);

If you allow enumerating from 0 incrementaly then integer_sequence would work:

#include <iostream>
#include <utility>
using namespace std;

enum Animal {
    DOG = 0,
    CAT, 
    NUM_ANIMALS
};

template <Animal A>
void animalVoice();

template <>
void animalVoice<DOG>() { cout << "Bau" << endl; }

template <>
void animalVoice<CAT>() { cout << "Meow" << endl; }

template <size_t... Args>
void call_animalVoice()
{
    (animalVoice<static_cast<Animal>(Args)>(), ...);
}

template <size_t... Args>
void call_animalVoice(integer_sequence<size_t, Args...>)
{
    call_animalVoice<Args...>();
}

int main()
{
    call_animalVoice(make_integer_sequence<size_t, NUM_ANIMALS>{});
}

Live Demo on Wandbox

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM