問題說來很簡單,結果我花了好久才搞懂,字字血淚
我想要的只有這樣的效果
1 | template <std::size_t i> |
結果這樣是無法編譯的,只好找其他方法繞過
Solution 1: Template specialization
一樣是從別人的Code上學來的
1 | template <std::size_t i> |
在這邊
_helper
會有兩個Template definition,而由於_helper<std::index_sequence<Idx...>>
的契合度比primary template好,所以會選擇這個definition- 然後就用fold expression展開了
- 不過實在是太醜了,思考有無其他的方案
Fail attempt:
在求助於AI之下,嘗試了其他方案std::apply and std::make_integer_sequence
這個是Claude提供的結果是不能用,1
2
3
4
5template <size_t i> void inner() {}
template <size_t N>
void outer() {
std::apply([](auto... indices) { (inner<indices>(), ...); }, std::make_index_sequence<N>{});
}std::apply
需要接受一個tuple like
的參數,很可惜這不是
於是先擱置在一旁,不過這個方案接近我最後的方案,還是感激一下AICustom apply function
這個是GPT4-o提供的將fold expression隱藏於實作中,雖然不錯,不過這方法也是有其缺點1
2
3
4
5
6
7
8
9
10template <typename F, size_t... Indices>
void apply_impl(F&& f, std::index_sequence<Indices...>) {
(f(std::integral_constant<size_t, Indices>{}), ...);
}
struct outer {
template <std::size_t N>
void test() {
apply_impl([](auto index) { inner<index>(); }, std::make_index_sequence<N>{});
}
};
無法表示這樣的Pseudo code萬能的CharGPT也給了一個思路,拓展apply_impl1
2
3
4
5
6
7
8
9
10
11
12template <std::size_t i>
bool inner() {
if (i == 1) return false;
else return true;
}
tempplate <std::size_t N>
bool outer() {
for (std::size_t i = 0; i < N; i++)
if (!inner<i>()) return false;
return true;
}看起來可行,不過也是有自己的問題1
2
3
4
5
6
7
8
9
10
11
12template <typename F, size_t First, size_t... Rest>
bool apply_impl(F&& f, std::index_sequence<First, Rest...>) {
if (!f(std::integral_constant<size_t, First>{})) {
return false;
}
return apply_impl(f, std::index_sequence<Rest...>{});
}
template <typename F>
bool apply_impl(F&&, std::index_sequence<>) {
return true;
} - 當你邏輯改變,例如將all_true或城anyone_true的時候,上面的apply_impl就要改了
- 當Callback function有無回傳值的情況,就要考慮很多地方,整個邏輯也會變得支離破碎,不好維護
因此,想出了自己的方案Solution2: make_index_sequence_tuple
查了一下資料std::apply
接受的是tuple like
的類型,那麼就自己做出一個tuple like
的index_sequqence
就好了這樣就沒啥問題了1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20template <std::size_t... Idx>
constexpr auto _make_index_sequence_tuple(std::index_sequence<Idx...>)
{
return std::make_tuple(std::integral_constant<std::size_t, Idx>()...);
}
template <std::size_t N>
constexpr auto make_index_sequence_tuple()
{
return _make_index_sequence_tuple(std::make_index_sequence<N>{});
}
struct outer {
template <std::size_t N>
void test() {
std::apply([](auto... indices) {
(inner<indices>(), ...); },
make_index_sequence_tuple<N>()
);
}
};Conclusion
AI生成的Source Code還是不能照單全收,不過提供個思路總是好的
不過更好的方法應該是template for,不過不知會部會進標準