Я борюсь с некоторыми правилами того, что можно включить в расчеты времени компиляции. Здесь я написал код, который связывает уникальный идентификатор с каждым классом, который его запрашивает (и упрощенное имя для целей тестирования). Однако этот уникальный идентификатор нельзя использовать в качестве аргумента шаблона или части условия static_assert, потому что это не constexpr.
#include <cassert>
#include <cxxabi.h>
#include <iostream>
#include <typeinfo>
namespace UID {
static int nextID(void) {
static int stored = 0;
return stored++;
}
template<class C>
static int getID(void) {
static int once = nextID();
return once;
}
template<class C>
static const char *getName(void) {
static int status = -4;
static const char *output =
abi::__cxa_demangle(typeid(C).name(), 0, 0, &status);
return output;
}
}
namespace Print {
template<class C>
std::ostream& all(std::ostream& out) {
return out << "[" << UID::getID<C>() << "] = "
<< UID::getName<C>() << std::endl;
}
template<class C0, class C1, class... C_N>
std::ostream& all(std::ostream& out) {
return all<C1, C_N>(all<C0>(out));
}
}
void test(void) {
Print::all<int, char, const char*>(std::cout) << std::endl;
// [0] = int
// [1] = char
// [2] = char const*
Print::all<char, int, const char*>(std::cout);
// [1] = char
// [0] = int
// [2] = char const*
}
Если это неясно, я хотел бы изменить другое поведение во время компиляции на основе идентификатора. Я видел несколько подходов, в которых используется связанный список типов, так что идентификатор представляет собой сумму ранее назначенного идентификатора constexpr и смещения constexpr. Однако я не вижу, чем это лучше, чем назначение идентификаторов вручную. Если бы вам нужно было отсортировать один список классов по их идентификаторам, а затем обернуть каждый из классов и запросить идентификаторы для оберток, идентификаторы будут зависеть от сортировки; тогда, чтобы определить «последний» элемент, вам придется либо отсортировать элементы вручную! Что мне не хватает?
tmp
? Я не понимаю. - person YSC   schedule 30.12.2015