您可以创建 constexpr 字符串数组和列表类型的元组来创建映射 list type -> index -> name(如果您需要映射 index -> types containing strings,只需使用元组而不是数组)。 c++17 方法可能如下所示:
#include <type_traits>
#include <tuple>
#include <utility>
#include <iostream>
struct LicencesList{};
struct BundlesList{};
struct ProductsList{};
struct UsersList{};
using ListTypes = std::tuple<LicencesList, BundlesList, ProductsList, UsersList>;
constexpr const char *NameList[] = {"licences", "bundles", "products", "users"};
template <class Tup, class, class = std::make_index_sequence<std::tuple_size<Tup>::value>>
struct index_of;
template <class Tup, class T, std::size_t... Is>
struct index_of<Tup, T, std::index_sequence<Is...>> {
static constexpr std::size_t value = ((std::is_same<std::tuple_element_t<Is, Tup>, T>::value * Is) + ...);
};
template<class ListT> static const char constexpr * GetNameOfList(void) {
return NameList[index_of<ListTypes, ListT>::value];
}
int main() {
constexpr const char *value = GetNameOfList<BundlesList>();
std::cout << value << std::endl;
}
[live demo]
如果你想保持 c++11 的兼容性,该方法会稍微长一点(我在这里使用Casey's answer 来实现index_of 结构):
#include <type_traits>
#include <tuple>
#include <iostream>
struct LicencesList{};
struct BundlesList{};
struct ProductsList{};
struct UsersList{};
using ListTypes = std::tuple<LicencesList, BundlesList, ProductsList, UsersList>;
constexpr const char *NameList[] = {"licences", "bundles", "products", "users"};
template <class Tuple, class T>
struct index_of;
template <class T, class... Types>
struct index_of<std::tuple<T, Types...>, T> {
static const std::size_t value = 0;
};
template <class T, class U, class... Types>
struct index_of<std::tuple<U, Types...>, T> {
static const std::size_t value = 1 + index_of<std::tuple<Types...>, T>::value;
};
template<class ListT> static const char constexpr * GetNameOfList(void) {
return NameList[index_of<ListTypes, ListT>::value];
}
int main() {
constexpr const char *value = GetNameOfList<BundlesList>();
std::cout << value << std::endl;
}
[live demo]