템플릿을 트리 같은 방법으로 인스턴스화하고 현재 방문한 노드를 추적하여이를 수행 할 수 있습니다.
namespace detail{
//This is used to store the visited nodes
template<int...> struct int_pack;
//Primary template
template<typename, int... I>
struct C;
//This is the leaf node
template<int... Is>
struct C<int_pack<Is...>> {
//The loop body goes here
static void f() {
std::cout << __PRETTY_FUNCTION__ << '\n';
}
};
//This is the recursive case
template <int I, int... Is, int... PIs>
struct C<int_pack<PIs...>, I,Is...> {
template <std::size_t... Idx>
static void f_help (std::index_sequence<Idx...>) {
//Store the current node in the pack
//and call `C::f` for each loop iteration
(void)std::initializer_list<int> {
(C<int_pack<PIs...,Idx>,Is...>::f(), 0)...
};
}
//Use tag dispatching to generate the loop iterations
static void f() {
f_help(std::make_index_sequence<I>{});
}
};
}
//Helper alias
template<int... Is>
using C = detail::C<detail::int_pack<>, Is...>;
사용법은 매우 간단하다 :
연타에
C<2,3>::f();
이 인쇄 : 당신이 주입 할 수 있도록이 더 일반적인 만들 수
static void detail::C<detail::int_pack<0, 0>>::f() [I = <>]
static void detail::C<detail::int_pack<0, 1>>::f() [I = <>]
static void detail::C<detail::int_pack<0, 2>>::f() [I = <>]
static void detail::C<detail::int_pack<1, 0>>::f() [I = <>]
static void detail::C<detail::int_pack<1, 1>>::f() [I = <>]
static void detail::C<detail::int_pack<1, 2>>::f() [I = <>]
Live Demo
루프 몸체 람다 (lambda)를 통해 클래스에 추가 할 수 있지만 위의 해결 방법은 한 번만 수행하고 다른 종속성을 가져 오지 않으려면 boost::hana
과 같이 수행해야합니다.
namespace detail{
template<int...> struct int_pack;
template<typename, int... I>
struct C;
template<int... Is>
struct C<int_pack<Is...>> {
template <typename Func>
static void f(const Func& func) {
func(Is...);
}
};
template <int I, int... Is, int... PIs>
struct C<int_pack<PIs...>, I,Is...> {
template <std::size_t... Idx, typename Func>
static void f_help (std::index_sequence<Idx...>, const Func& func) {
(void)std::initializer_list<int>{ (C<int_pack<PIs...,Idx>,Is...>::f(func), 0)... };
}
template <typename Func>
static void f(const Func& func) {
f_help(std::make_index_sequence<I>{}, func);
}
};
}
당신은과 같이이를 사용합니다 :
C<2,3>::f([](int i, int j){
std::cout << "i " << i << " j " << j << '\n';
});
Live Demo
여기에 더 일반적인 버전의 가능한 구현이다 (당신은 완벽하게 전달 등으로 개선 할 수)
여기 boost::hana
으로 조롱 한 빠른 버전이 있습니다. 이 작업을 수행하는 더 좋은 방법이 있지만 이것이 수행 할 수있는 작업에 대한 아이디어를 제공해야합니다.
template <typename Func>
void unroll (const Func& func) {
func();
}
template <std::size_t I1, std::size_t... Is, typename Func>
void unroll (const Func& func) {
hana::for_each(hana::range_c<std::size_t, 0, I1>,
[&](auto x) {
unroll<Is...>([x, &func] (auto... xs) { func(x,xs...); });
});
}
답변에서 '부스트 : 하나'를 언급 해 주셔서 감사합니다. 저는 지난 며칠 동안 그것에 대해 더 많이 배웠습니다. 도서관에 익숙하고 여유 시간이 있다면, 그것을 사용하는 솔루션을 게시 할 수 있는지 궁금합니다. –
@TeodorNikolov 나는 도서관에 익숙하지 않다.나는 그걸 시도하고 프로젝트의 [Gitter] (https://gitter.im/boostorg/hana)에 도움을 청하기를 권하고 싶다. 거기에 한 두 번 게시했습니다. 제작자는 매우 친절합니다. – TartanLlama
@TeodorNikolov'boost :: hana'에서 어떻게 할 수 있었는지에 대한 간단한 아이디어를 썼다.하지만 아마 스스로 조사하는 것이 가장 좋다. – TartanLlama