Получение элемента кортежа по типу (до C ++ 0x)

У меня есть шаблонный класс, который содержит кортеж и хочу иметь возможность получать элементы по типу во время компиляции. Для упрощения контейнерный класс ограничен максимум тремя записями:

template< class U = null_type, class V = null_type, class W = null_type >
class TupleContainer {
public:

template< class ReturnT >
ReturnT& getElementbyType() {
return get< ReturnT >(data_);
}

private:
boost::tuple< U, V, W > data_;
}

Чтение ответов на Получить индекс типа элемента кортежа а также Для std :: tuple, как получить данные по типу и как получить тип по индексу? Я достиг этого благодаря рекурсивному подходу к посетителям, и он прекрасно работает, используя компилятор GNU C ++ с функциями c ++ 11.

template< int Index, class Search, class First, class... Types >
struct get_internal
{
typedef typename get_internal< Index + 1, Search, Types...>::type type;
static constexpr int index = Index;
};

template< int Index, class Search, class... Types >
struct get_internal< Index, Search, Search, Types... >
{
typedef get_internal type;
static constexpr int index = Index;
};

template< class T, class... Types >
T& get( std::tuple< Types... >& tuple )
{
return std::get< get_internal< 0, T, Types... >::type::index >(tuple);
}

Теперь я должен перенести мой код в Windows. Из-за ограничений какой-либо внешней библиотеки я вынужден использовать Visual Studio 2010, которая, похоже, не поддерживает шаблоны с переменными параметрами.

Я уверен, что есть обходной путь (так как boost :: tuple также доступен без поддержки вариадических шаблонов), но я все еще новичок во всей этой теме метапрограммирования шаблонов и пока не нашел решения.

Так кто-нибудь знает способ решить эту проблему без использования вариадических шаблонов в Visual Studio 2010?

КСТАТИ: Подход посетителей хорошо работает даже с кортежами с более чем тремя элементами. Контейнер будет ограничен тремя или четырьмя элементами кортежей, так что я бы даже не стал жестко кодировать индексы в моей реализации.

1

Решение

Вам не нужен препроцессор для генерации большого количества перегрузок, просто адаптируйте ваш get_internal подход к работе без вариадических шаблонов. Они должны иметь такое же количество параметров, как TupleContainer:

template< class R, class U, class V, class W >
struct getIndex
{
static const int value = getIndex< R, V, W, null_type >::value + 1;
};

template< class R, class V, class W >
struct getIndex< R, R, V, W >
{
static const int value = 0;
};

template< class R >
struct getIndex< R, null_type, null_type, null_type >
{
// let it fail if the type is not found and avoid infinite recursion
};

и теперь вы можете использовать

template< class R >
R& getElementByType() {
return get< getIndex< R, U, V, W >::value >(data_);
}
0

Другие решения

Других решений пока нет …