LINUX.ORG.RU

История изменений

Исправление pavlick, (текущая версия) :

Ты, наверное, хочешь странного и можно как-то по-другому, но всё же родил вот такое:

#include <variant>
#include <array>
#include <iostream>
using namespace std;

template<int nd>
class foo_t{
	std::variant<int,double> d;
};

#define FOO_LIST    \
	LIST_HELPER(0), \
	LIST_HELPER(1), \
	LIST_HELPER(2), \
	LIST_HELPER(3), \
	LIST_HELPER(4)

#define LIST_HELPER(foo_ind) foo_t<foo_ind>
class foo_holder : public std::variant<FOO_LIST>{
#undef LIST_HELPER
	template<int nd>
	operator foo_t<nd>& () const {
		return std::get<foo_t<nd>>(*this);
	}
};

enum class Flags {one, two, three, size};

template<int nd, Flags flag>
void proc_foo_f(void *data) {foo_t<nd> *p = static_cast<foo_t<nd>*>(data);}

consteval auto prof_foo_f_array()
{
	static_assert(static_cast<int>(Flags::size) == 3);
#define LIST_HELPER(foo_ind)             \
	&proc_foo_f<foo_ind, Flags::one>,    \
	&proc_foo_f<foo_ind, Flags::two>,    \
	&proc_foo_f<foo_ind, Flags::three>
	array res {
		FOO_LIST
	};
#undef LIST_HELPER
	return res;
}

int main() {
	auto a = prof_foo_f_array();
	cout << a.size() << endl;     // 15
	for (auto f : a)
		f(nullptr);
	return 0;
}

ЗЫ: индексация в массиве - не проблема, естественно.
Хотя твою задачу целиком все же не решил, не продумал каст здесь: case FLAG1: return proc_foo_f<1,1>(foo);

Исправление pavlick, :

Ты, наверное, хочешь странного и можно как-то по-другому, но всё же родил вот такое:

#include <variant>
#include <array>
#include <iostream>
using namespace std;

template<int nd>
class foo_t{
	std::variant<int,double> d;
};

#define FOO_LIST    \
	LIST_HELPER(0), \
	LIST_HELPER(1), \
	LIST_HELPER(2), \
	LIST_HELPER(3), \
	LIST_HELPER(4)

#define LIST_HELPER(foo_ind) foo_t<foo_ind>
class foo_holder : public std::variant<FOO_LIST>{
#undef LIST_HELPER
	template<int nd>
	operator foo_t<nd>& () const {
		return std::get<foo_t<nd>>(*this);
	}
};

enum class Flags {one, two, three, size};

template<int nd, Flags flag>
void proc_foo_f(void *data) {foo_t<nd> *p = static_cast<foo_t<nd>*>(data);}

consteval auto prof_foo_f_array()
{
	static_assert(static_cast<int>(Flags::size) == 3);
#define LIST_HELPER(foo_ind)             \
	&proc_foo_f<foo_ind, Flags::one>,    \
	&proc_foo_f<foo_ind, Flags::two>,    \
	&proc_foo_f<foo_ind, Flags::three>
	array res {
		FOO_LIST
	};
#undef LIST_HELPER
	return res;
}

int main() {
	auto a = prof_foo_f_array();
	cout << a.size() << endl;     // 15
	for (auto f : a)
		f(nullptr);
	return 0;
}

ЗЫ: индексация в массиве - не проблема, естественно.

Исходная версия pavlick, :

Ты, наверное, хочешь странного и можно как-то по-другому, но всё же родил вот такое:

#include <variant>
#include <array>
#include <iostream>
using namespace std;

template<int nd>
class foo_t{
	std::variant<int,double> d;
};

#define FOO_LIST    \
	LIST_HELPER(0), \
	LIST_HELPER(1), \
	LIST_HELPER(2), \
	LIST_HELPER(3), \
	LIST_HELPER(4)

#define LIST_HELPER(foo_ind) foo_t<foo_ind>
class foo_holder : public std::variant<FOO_LIST>{
#undef LIST_HELPER
	template<int nd>
	operator foo_t<nd>& () const {
		return std::get<foo_t<nd>>(*this);
	}
};

enum class Flags {one, two, three, size};

template<int nd, Flags flag>
void proc_foo_f(void *data) {foo_t<nd> *p = static_cast<foo_t<nd>*>(data);}

consteval auto prof_foo_f_array()
{
	static_assert(static_cast<int>(Flags::size) == 3);
#define LIST_HELPER(foo_ind)             \
	&proc_foo_f<foo_ind, Flags::one>,    \
	&proc_foo_f<foo_ind, Flags::two>,    \
	&proc_foo_f<foo_ind, Flags::three>
	array res {
		FOO_LIST
	};
#undef LIST_HELPER
	return res;
}

int main() {
	auto a = prof_foo_f_array();
	cout << a.size() << endl;     // 15
	for (auto f : a)
		f(nullptr);
	return 0;
}