本文展示了遍歷std::tuple
的方式:
首先比較容易想到的是利用C++14的std::make_index_sequence
與std::get
結(jié)合取值,然后配合std::initializer_list
進(jìn)行包展開:
// since C++14
class Func0 {
template<typename T, typename F, size_t... I>
void init(T&& t, F&& f, std::index_sequence<I...>) {
std::initializer_list<int>{ (f(std::get<I>(t)), 0)... };
}
public:
template<typename T, typename F>
auto operator()(T&& t, F&& f) {
init(t, f, std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<T>>>{});
}
};
到了C++17,我們有了折疊表達(dá)式(Fold expressions),就可以直白一點(diǎn)了:
// since C++17
class Func1 {
template<typename T, typename F, size_t... I>
void init(T&& t, F&& f, std::index_sequence<I...>) {
((f(std::get<I>(t))), ...);
}
public:
template<typename T, typename F>
auto operator()(T&& t, F&& f) {
init(t, f, std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<T>>>{});
}
};
C++20允許lambda添加模板參數(shù),因此我們可以進(jìn)一步限制這個(gè)遍歷器的作用域:
// since C++20
auto Func2 = []<typename T, typename F>(T && t, F && f) {
[&] <size_t ...I>(std::index_sequence<I...>) {
((f(std::get<I>(t))), ...);
}(std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<T>>>{});
};
然后我們還可以利用C++17提供給我們的std::apply
取值:
// since C++17
class Func3 {
public:
template<typename T, typename F>
auto operator()(T&& t, F&& f) {
std::apply(
[&f](auto&&... args) {
((f(args)), ...);
}, t
);
}
};
或者干脆把這個(gè)std::apply給拿出來(lái),這種應(yīng)該算是最簡(jiǎn)單的:
// since C++17
std::apply(
[&PrintV](auto&&... args) {
((PrintV(args)), ...);
}, t
);
完整測(cè)試程序:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-654615.html
#include <iostream>
#include <tuple>
#include <type_traits>
#include <initializer_list>
// since C++14
class Func0 {
template<typename T, typename F, size_t... I>
void init(T&& t, F&& f, std::index_sequence<I...>) {
std::initializer_list<int>{ (f(std::get<I>(t)), 0)... };
}
public:
template<typename T, typename F>
auto operator()(T&& t, F&& f) {
init(t, f, std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<T>>>{});
}
};
// since C++17
class Func1 {
template<typename T, typename F, size_t... I>
void init(T&& t, F&& f, std::index_sequence<I...>) {
((f(std::get<I>(t))), ...);
}
public:
template<typename T, typename F>
auto operator()(T&& t, F&& f) {
init(t, f, std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<T>>>{});
}
};
// since C++17
class Func3 {
public:
template<typename T, typename F>
auto operator()(T&& t, F&& f) {
std::apply(
[&f](auto&&... args) {
((f(args)), ...);
}, t
);
}
};
int main(int argc, char* argv[])
{
// 測(cè)試一下
// auto t = std::make_tuple(1, 2.f, 3., '4', "5"); // for C++14
std::tuple t(1, 2.f, 3., '4', "5");
auto PrintV = [](auto&& v) { std::cout << v << ' '; };
Func0()(t, PrintV);
std::cout << "\n\n";
Func1()(t, PrintV);
std::cout << "\n\n";
// since C++20
auto Func2 = []<typename T, typename F>(T && t, F && f) {
[&] <size_t ...I>(std::index_sequence<I...>) {
((f(std::get<I>(t))), ...);
}(std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<T>>>{});
};
Func2(t, PrintV);
std::cout << "\n\n";
Func3()(t, PrintV);
std::cout << "\n\n";
// since C++17
std::apply(
[&PrintV](auto&&... args) {
((PrintV(args)), ...);
}, t
);
std::cout << "\n\n";
return 0;
}
輸出結(jié)果:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-654615.html
到了這里,關(guān)于C++遍歷std::tuple(C++14 ~ C++20)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!