将整数序列与元组和可变参数模板一起使用
Using integer sequences with tuples and variadic templates
假设我有一个元组:
std::tuple<int, char, unsigned int> t{1, 'a', 4}
如何使用 std::index_sequence
和朋友迭代上述元组的类型,以便我可以使用(或在需要时重写)下面的函数 to_token
?
template<typename P1, typename... Param>
std::vector<std::string> to_token(const P1& p1, const Param&... param) {
const auto to_token_impl = [](const auto& t) {
using ParamType = std::decay_t<decltype(t)>;
std::stringstream ss;
if constexpr (std::is_same_v<ParamType, char>)
ss << "char";
else if constexpr (std::is_integral_v<ParamType>) {
ss << "integral";
}
return ss.str();
};
return {to_token_impl(p1), to_token_impl(param)...};
}
预期输出:{ "integral", "char", "integral" }
根据 here 找到的示例,我已经开始研究这种间接方法,但我无法确定下一步该做什么...
template<typename... Args>
void tokenize(const std::tuple<Args...>& t) {
tokenize_impl(t, std::index_sequence_for<Args...>{});
}
template<typename Tuple, std::size_t... Is>
void tokenize_impl(const Tuple& t, std::index_sequence<Is...>) {
// ?
}
template<typename... Args>
decltype(auto) tokenize(const std::tuple<Args...>& t) {
return std::apply(
[](auto const &... o) -> decltype(auto) { return to_token(o...); },
t
);
}
lambda需要推迟to_token
的参数推导,直到它真正发生在std::apply
内部,否则to_token
没有明确的类型,无法传递作为参数。
std::string typeToString(int) {
return "integral";
}
std::string typeToString(char) {
return "char";
}
// overload this method to support other types
template<typename Tuple, std::size_t... Is>
auto tokenize_impl(const Tuple& t, std::index_sequence<Is...>) {
return std::vector<std::string>( {typeToString(std::get<Is>(t))...} );
}
template<typename... Args>
auto tokenize(const std::tuple<Args...>& t) {
return tokenize_impl(t, std::index_sequence_for<Args...>{});
}
int main() {
auto t = std::make_tuple(1,'a',4);
auto res = tokenize(t);
for (auto elem : res)
std::cout << elem << std::endl;
}
作为输出:
integral
char
integral
假设我有一个元组:
std::tuple<int, char, unsigned int> t{1, 'a', 4}
如何使用 std::index_sequence
和朋友迭代上述元组的类型,以便我可以使用(或在需要时重写)下面的函数 to_token
?
template<typename P1, typename... Param>
std::vector<std::string> to_token(const P1& p1, const Param&... param) {
const auto to_token_impl = [](const auto& t) {
using ParamType = std::decay_t<decltype(t)>;
std::stringstream ss;
if constexpr (std::is_same_v<ParamType, char>)
ss << "char";
else if constexpr (std::is_integral_v<ParamType>) {
ss << "integral";
}
return ss.str();
};
return {to_token_impl(p1), to_token_impl(param)...};
}
预期输出:{ "integral", "char", "integral" }
根据 here 找到的示例,我已经开始研究这种间接方法,但我无法确定下一步该做什么...
template<typename... Args>
void tokenize(const std::tuple<Args...>& t) {
tokenize_impl(t, std::index_sequence_for<Args...>{});
}
template<typename Tuple, std::size_t... Is>
void tokenize_impl(const Tuple& t, std::index_sequence<Is...>) {
// ?
}
template<typename... Args>
decltype(auto) tokenize(const std::tuple<Args...>& t) {
return std::apply(
[](auto const &... o) -> decltype(auto) { return to_token(o...); },
t
);
}
lambda需要推迟to_token
的参数推导,直到它真正发生在std::apply
内部,否则to_token
没有明确的类型,无法传递作为参数。
std::string typeToString(int) {
return "integral";
}
std::string typeToString(char) {
return "char";
}
// overload this method to support other types
template<typename Tuple, std::size_t... Is>
auto tokenize_impl(const Tuple& t, std::index_sequence<Is...>) {
return std::vector<std::string>( {typeToString(std::get<Is>(t))...} );
}
template<typename... Args>
auto tokenize(const std::tuple<Args...>& t) {
return tokenize_impl(t, std::index_sequence_for<Args...>{});
}
int main() {
auto t = std::make_tuple(1,'a',4);
auto res = tokenize(t);
for (auto elem : res)
std::cout << elem << std::endl;
}
作为输出:
integral
char
integral