Долгое время назад я видел нерекурсивную реализацию, чтобы получить последнее значение/тип из последовательности последовательностей/значений типа. Он имеет приятное свойство, что количество созданных шаблонов является независимым (и постоянным) количеством элементов, содержащихся в последовательности.Возможно ли реализовать нерекурсивную реализацию at_c?
Реализация проста, как следует
// a struct that eats anything and everything
struct eat { template<class T> eat(T&&) {} };
// generates V matching with U
template<class U, class V> struct match { using type = V; };
template<class... X> struct back_
{
template<class U>
static U&& get(typename match<X, eat>::type..., U&& u)
{
return static_cast<U&&>(u); // forward
}
};
// simple macro to avoid repetition for trailing return type.
#define RETURNS(exp) -> decltype(exp) { return exp; }
// get the last value in meta O(1)
template<class T, class... Ts>
auto back(T&& t, Ts&&... ts) RETURNS(back_<Ts...>::get(static_cast<T&&>(t), static_cast<Ts&&>(ts)...))
Он использует простой факт, что данный тип в VARIADIC X...
компилятор может нерекурсивно создать другой тип T
целых X
s там.
Итак, я хочу знать, есть ли способ расширить его для реализации функции at_c
или nth
с постоянным количеством экземпляров шаблонов (независимо от количества элементов).
Он также может быть сформулирован, как, дают VARIADIC тип X...
и некоторое целое число N
, можно ли нерекурсивно генерировать подпоследовательность X...
, состоящую из элементов N
?
Вы можете просто предоставить бесконечное количество перегрузок, которые вручную имеют 1, 2, 3, 4, 6, ... первые параметры и прочее. Кроме этого, лучшее, что вы можете получить, это 'log N', я считаю. – Xeo
@Xeo Вы должны уметь «log log N» с достаточно быстро растущей рекурсией? Довольно бессмысленно, поскольку предел 1000 рекурсий под 'log N' находится почти бесконечно далеко, а накладные расходы на выведение глубины рекурсии« log log N »будет выше, чем разница для любого разумного« N »... – Yakk
Пожалуйста, остановите используя 'static_cast'. У нас есть ['std :: forward'] (http://en.cppreference.com/w/cpp/utility/forward) по какой-то причине: он гораздо читабельнее и на самом деле говорит читателю * почему * вы это делаете , в отличие от 'static_cast', который является тайным и бессмысленным для тех, кто не знает. –