Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第四章 std::tuple 的遍历的内容有些过时与复杂 #294

Open
Mq-b opened this issue Jun 9, 2024 · 3 comments
Open

第四章 std::tuple 的遍历的内容有些过时与复杂 #294

Mq-b opened this issue Jun 9, 2024 · 3 comments

Comments

@Mq-b
Copy link
Contributor

Mq-b commented Jun 9, 2024

现在基本上来说谈起遍历元组,无非就是多套一层,然后 std::index_sequence + std::make_index_sequence 解决。

标准高的话用 C++17 折叠表达式,或者 C++20 引入的lambda显式写明模板参数,也就是:

template<typename Func, typename... Args>
void iterate_tuple(Func f, const std::tuple<Args...>& tuple) {
    [&]<std::size_t... idx>(std::index_sequence<idx...>){
        (f(std::get<idx>(tuple)), ...);
    }(std::make_index_sequence<sizeof...(Args)>());
}

int main(){
    auto print = [](const auto& v){
        std::cout << v << ' ';
    };
    std::tuple<int, double, std::string> tuple{ 1,1.2,"😅" };
    iterate_tuple(print, tuple);
}

非常的简单直观,godbolt

原文使用的 std::variant 让我觉得很诡异。

https://changkun.de/modern-cpp/zh-cn/04-containers/#%E8%BF%90%E8%A1%8C%E6%9C%9F%E7%B4%A2%E5%BC%95

@frederick-vs-ja
Copy link
Contributor

frederick-vs-ja commented Jun 12, 2024

感觉……不如 std::apply

std::apply([&f](auto&&...args) { ((void)f(static_cast<decltype(args)>(args)), ...); }, tuple);

//

constexpr auto multi_to_single_dispatcher = [](auto&& f) // 避免重复产生不同的闭包类型
{
    return [&f](auto&&...args) { ((void)f(static_cast<decltype(args)>(args)), ...); };
};
// ...
std::apply(multi_to_single_dispatcher(f), tuple);

@Mq-b
Copy link
Contributor Author

Mq-b commented Jun 12, 2024

这个也有道理,不过我看这里是想自己搓的意思,而不是调库,就没提,乐。

@frederick-vs-ja
Copy link
Contributor

看起来这部分需要推倒重来。运行时选择 tuple 下标应该是个相对没那么常用的需求,适合放到最后。或者和其他类型擦除的手段一起讲。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants