You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++17中用{fmt}格式化转换后容器且无需创建新容器?

在C++17中无需创建新容器即可用{fmt}打印转换后的容器元素

C17没有内置的视图库(C20才引入std::views::transform),但可以通过实现轻量级的转换范围适配器,配合{fmt}库的fmt::join实现无需创建新容器的打印需求。

实现轻量级转换范围适配器

写一个模板包装类,包装原容器和转换函数,仅在迭代元素时实时应用转换逻辑,不复制任何元素:

#include <fmt/core.h>
#include <fmt/ranges.h>
#include <vector>
#include <cmath>
#include <utility>

// 包装转换逻辑的范围类
template <typename Range, typename Func>
struct TransformRange {
    const Range& source;
    Func transform;

    // 自定义迭代器,仅在解引用时应用转换
    struct Iterator {
        using BaseIter = typename Range::const_iterator;
        BaseIter current;
        Func func;

        decltype(auto) operator*() const { return func(*current); }
        Iterator& operator++() { ++current; return *this; }
        bool operator!=(const Iterator& other) const { return current != other.current; }
    };

    Iterator begin() const { return {source.begin(), transform}; }
    Iterator end() const { return {source.end(), transform}; }
};

// 辅助函数,简化转换范围的创建
template <typename Range, typename Func>
auto make_transform_view(const Range& range, Func func) {
    return TransformRange<Range, Func>{range, std::move(func)};
}

int main() {
    std::vector<double> vec = {1., 2., 3.};
    // 直接传入转换视图给fmt::join,无需创建新容器
    fmt::print("{:0.3f}\n", fmt::join(
        make_transform_view(vec, [](double x) { return x * M_PI; }),
        ","
    ));
}

说明

这个实现的核心是延迟转换:只有当{fmt}库迭代访问元素准备打印时,才会调用转换函数计算结果,全程不会复制原容器的元素,内存开销可以忽略。

内容的提问来源于stack exchange,提问作者auzn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 22:22:45