如何在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
相关产品推荐
相关产品推荐

