Я пытаюсь постепенно создать список типов, регистрируя типы с помощью макроса. Для этого я хочу использовать трюк, который я нашел в ответе на другой вопрос. Сокращенный код выглядит следующим образом:
#include <iostream>
#include <type_traits>
#include <utility>
#include <tuple>
#define MAXIMUM_SIZE 100
template <std::size_t N>
struct Index : Index<N - 1> {};
template <>
struct Index<0> {};
std::tuple<> GetTypes(Index<0>) { return {}; }
#define GET_REGISTERED_TYPES \
decltype(GetTypes(std::declval<Index<MAXIMUM_SIZE>>()))
#define REGISTER_TYPE(Type) \
inline decltype(std::tuple_cat( \
std::declval<GET_REGISTERED_TYPES>(), \
std::declval<std::tuple<Type>>())) \
GetTypes(Index<std::tuple_size_v<GET_REGISTERED_TYPES> + 1>) { \
return {}; \
}
REGISTER_TYPE(int)
REGISTER_TYPE(float)
REGISTER_TYPE(char)
REGISTER_TYPE(Index<78>)
int main() {
// true
std::cout << std::boolalpha
<< std::is_same_v<
GET_REGISTERED_TYPES,
std::tuple<int, float, char, Index<78>>>
<< std::endl;
}
Этот тип кода считается безопасным для использования или является частью некоторых неясных частей языка и не должен использоваться для производства , Кроме того, у меня не возникает вопроса о полном метапрограммировании из-за комментария. Единственное, что делает макрос REGISTER_TYPE
, это объявляет перегруженную функцию NEW. Как это можно считать изменением состояния?
Чтобы этот трюк перестал работать, необходимо внести некоторые фундаментальные изменения в правила выбора функции перегрузки в c ++ с тем, чтобы каждая промежуточная программа прекратила компиляцию. Я прав?