【问题标题】:Using integer sequences with tuples and variadic templates使用带有元组和可变参数模板的整数序列
【发布时间】:2026-02-16 07:20:02
【问题描述】:

假设我有一个元组:

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...>) {
    // ?
}

【问题讨论】:

    标签: c++ tuples c++17 variadic-templates template-meta-programming


    【解决方案1】:
    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 没有明确的类型并且不能作为参数传递。

    【讨论】:

    • 哇...好吧,显然错过了!模板推演失败in this demo,知道为什么吗?
    • @Fluffy 为什么,为什么,为什么我在没有先测试的情况下继续发布答案。修复正在进行中...
    【解决方案2】:
    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
    

    Live demo

    【讨论】:

    • 太棒了,正是我写的失败。谢谢!
    最近更新 更多