В этом видео я нашел следующий код, и мне очень понравилось.Определение пользовательских типов в шаблоне метапрограммирования
#include <iostream>
using namespace std;
#define LIST1(T1) Node<T1,Null>
#define LIST2(T1,T2) Node<T1,LIST1(T2)>
#define LIST3(T1,T2,T3) Node<T1,LIST2(T2,T3)>
#define LIST4(T1,T2,T3,T4) Node<T1,LIST3(T2,T3,T4)>
struct Null { };
template <int X, typename Next>
struct Node {
static const int val = X;
typedef Next Next_;
};
template <typename List>
struct Sum
{
static const int sum = List::val + Sum<typename List::Next_>::sum;
};
template <>
struct Sum<Null> {
static const int sum = 0;
};
int main()
{
cout << Sum<LIST4(2, 2, 3, 4)>::sum << endl;
}
Мой вопрос в том, что это лучший способ сделать это? Какими другими способами я должен заниматься подобным разбором? Основная проблема, которую я вижу, - это директива препроцессора, используемая для определения типа. Есть ли другой способ сделать это?
Например, я хочу представлять IP-адрес такой же, как указано выше:
Sum<IP<120.100.10.20>>
, который будет анализировать входной сигнал.
Также, если это возможно взять из файла, было бы гораздо полезнее. Я думаю, что такие форматированные данные должны быть разрешены к типу в TMP. Как мне изменить код для поддержки этого?
Редактировать :: Добавление другого кода, который заставляет меня чувствовать, что это будет полезно.
#include <iostream>
#define LIST1(T1) Node<T1,Null>
#define LIST2(T1,T2) Node<T1,LIST1(T2)>
#define LIST3(T1,T2,T3) Node<T1,LIST2(T2,T3)>
#define LIST4(T1,T2,T3,T4) Node<T1,LIST3(T2,T3,T4)>
using namespace std;
// Highest bit in an IP address
template <typename List, int N, bool B>
struct highestBitSet
{
static const bool b = List::val & (1 << N);
static const int bit = highestBitSet<List, N - 1, b>::bit;
};
template <typename List, int N>
struct highestBitSet<List,N,true>
{
static const int bit = N+1;
};
template <typename List>
struct highestBitSet<List, -1, false>
{
static const int bit = 8+highestBitSet<List::Next_, 7, false>::bit;
};
template <int X>
struct highestBitSet<Null, X, false>
{
static const int bit = 0;
};
int main()
{
// Will print 0
cout << highestBitSet<LIST4(1, 0, 0, 0), 7, false>::bit << endl;
// WIll print 31
cout << highestBitSet<LIST4(0, 0, 0, 255), 7, false>::bit << endl;
return 0;
}
Это похоже на решение для бедного человека (C++ 98 bound) для переменных параметров шаблонов шаблонов. Добро пожаловать в текущее десятилетие. –
@ πάνταῥεῖ Действительно, это похоже на то, что делает Андрей Александреску в своей книге Modern C++ Design для списков типов. – user2296177
@ πάνταῥεῖ Извините, я не очень хорошо знаком со старой мыслью и новыми реализациями. Можете ли вы направить меня? –