Итак, у меня была своего рода шаблонная функция
template<int i> task();
Вы также можете думать об этом как о типе с соответствующим конструктором, если это необходимо.
template<int i> struct task{ task();};
И я хотел бы повторить i через интервал.
Что значит,
task<0>(); task<1>(); ... task<ConstantVal>();
Кроме того, я хотел бы использовать тот же стиль, что и при написании любого обычного цикла for, то есть я бы хотел избежать создания класса шаблона каждый раз, когда сталкиваюсь с подобной ситуацией. Вместо этого я хотел бы просто использовать шаблон, скажем, template<int s, int j, class callable> struct ForLoop;, и просто применить что-то вроде ForLoop<s,t,taskTemplate>()
Но от меня требуется передать шаблон в качестве аргумента, что не является синтаксически законным. Есть ли какое-то решение для такого рода повторяющихся проблем?
Ниже приведены некоторые обходные пути. Но я не думаю, что это отличное решение по причинам, о которых я упоминал выше.
template<int s, int t>
struct ForLoop{
ForLoop(){
task<s>(); ForLoop<s+1,t>::ForLoop();
}
};
template<int s>
struct ForLoop<s,s>{
ForLoop(){}
};
Отображение некоторого псевдокода или примера кода значительно прояснит ваш вопрос.
Если вы хотите перебрать task<i>, зачем вы создаете его как шаблон? Это создает семейство task, а не один тип, для которого значение i может быть установлено во время выполнения - и это мешает тому, что вы ищете.
@ryhp Я использую C++ 11. @Peter Потому что мне нужно получить доступ к другому объекту шаблона, который принимает только постоянные значения. @super Вот мой код, но я не думаю, что это хороший способ его реализовать. `` `шаблон <int s, int t> struct ForLoop {ForLoop () {задача <s> (); ForLoop <s + 1, t> :: ForLoop (); }}; шаблон <int s> struct ForLoop <s, s> {ForLoop () {}}; ``





Вы можете использовать что-то вроде (C++ 14):
template <std::size_t ... Is, typename F>
void ForEachIndex(std::index_sequence<Is...>, F&& f)
{
int dummy[] = {0, /* Handles empty Is. following cast handle evil operator comma */
(static_cast<void>(f(std::integral_constant<std::size_t, Is>())), 0)...};
static_cast<void>(dummy); // avoid warning for unused variable
}
template <std::size_t N, typename F>
void ForEachIndex(F&& f)
{
ForEachIndex(std::make_index_sequence<N>(), std::forward<F>(f));
}
Применение:
const auto start = 42;
ForEachIndex<4>([&](auto i){ task<start + i()>(); }); // task<42>(), .., task<45>()
Для C++ 11:
make_index_sequence / index_sequence может быть найдена.родовую лямбду следует заменить старым функтором:
struct MyFunctor {
template <std::size_t I>
void operator()(std::integral_constant<std::size_t, I>) const {
// ...
}
};
Какая часть вам непонятна? Вы также можете посмотреть «перебрать кортеж» для получения некоторых деталей.
На самом деле я не так хорошо знаком с C++ 14, но почему параметр лямбда может быть передан как параметр шаблона? Я имею в виду, что это переменная, не так ли?
Общая лямбда получит другой тип, например auto: std::integral_constant<std::size_t, 0>, .., std::integral_constant<std::size_t, N - 1>. Этот тип может предоставить I во время компиляции. Итак, мы называем f(std::integral_constant<std::size_t, 0>()), .., f(std::integral_constant<std::size_t, N - 1>()).
хорошо! но что делают integ_constant и index_sequence? Я все еще не могу это понять
index_sequence - это в основном (скомпилированная) коллекция std::size_t, integral_constant - это тип для обертывания постоянного значения в тип.
Какую версию C++ вы используете?