技术经验分享:fmt的API介绍(版本:7.0.1)

简介: 技术经验分享:fmt的API介绍(版本:7.0.1)

!!版权声明:本文为博主原创文章,版权归原文作者和博客园共有,谢绝任何形式的 转载!!


作者:mohist


本文翻译:


水平有限,仅供参考,欢迎指正。 有兴趣的,看看原文。


fmt版本: 7.0.1


--------------------------------------------------------------------------


A、介绍#


fmt库由一下模块组成:


  fmt/core.h:     提供参数处理的一系列接口 和 一个轻量级的格式化函数集合。


  fmt/format.h:   提供了用于编译时的格式化字符串检查、宽字符、迭代输出 和支持用户子自定义的接口。


  fmt/ranges.h:    提供了针对元组和容器ranges的额外的格式化支持


  fmt/chrono.h:    提供了时间和日期的格式化处理的接口


  fmt/compile.h:    格式化字符串编译


  fmt/ostream.h:   标准输出流的支持


  fmt/printf.h:    printf格式化


  fmt库提供的函数和类型都在fmt的命名空间下和加上了前缀 FMT_


  注意: fmt格式化都是在大括号 {}内。


B、core api


  0、包含头文件:


#include


  1、fmt::foroomat返回一个字符串。


std::string message = fmt::format("The answer is {}", 42);


  2、fmt::print标准输出, 与 std::cout的输出相仿


#include


fmt::print("Elapsed time: {0:.2f} seconds", 1.23);


  3、fmt::print支持写入文件,写入的字符串是用的UNICODE编码。函数原型如下:


template

void fmt::print(std::FILE f, const S &format_str, Args&&... args)


  函数的第一个参数是文件指针:


fmt::print(stderr, "Don't {}!", "panic");


  4、命名参数:通过指定参数名称的方式来调用参数。方便调用参数时按调用者的需要来排列顺序,而不必死守函数声明时的顺序,同时结合默认参数值的特性,可以选择使用默认参数还是不使用默认参数。 函数原型如下:


template


detail::named_arg fmt::arg(const Char name, const T &arg)


  该函数将返回一个用于函数参数的格式化字符串。使用方法:


fmt::print("Elapsed time: {s:.2f} seconds", fmt::arg("s", 1.23));


  注意: 命名参数不能在编译的时候检查格式化字符串的错误


  5、参数列表 Argument Lists


  5.1)、函数原型:


template


format_arg_store fmt::make_format_args(const Args&... args)


    构造一个format_arg_store对象,该对象包含对参数的引用,并且可以隐式转换为format_args。可以省略上下文,在这种情况下,它默认为上下文。


有关生命周期的考虑,请参见arg()。


  5.2)、class fmt::format_arg_store类


template


class fmt::format_arg_store


  引用参数的数组。可以将其隐式转换为basic_format_args,以传递给类型擦除的格式函数,例如vformat()。


  fmt::format_arg_store 的公有函数:


  5.2.1)、push_back函数原型


template


void push_back(const T &arg)


  该函数将参数arg自动添加到自动存储的内存中,以便传递给需要格式化参数的函数。


  请注意,如有必要,将自定义类型和字符串类型(但不包括字符串view)复制到存储中,以动态分配内存, 例如:


fmt::dynamic_format_arg_store store;


store.push_back(42);


store.push_back("abc");


store.push_back(1.5f);


std::string result = fmt::vformat("{} and {} and {}", store);


  5.2.2)、 push_back函数原型: 


template


void push_back(std::reference_wrapper arg)


  该函数将参数arg自动添加到自动存储的内存中,以便传递给需要格式化参数的函数。通过std :: ref()/ std :: cref()的引用,支持包装在std :: reference_wrapper中的命名参数。例如:


fmt::dynamic_format_arg_store store;


char str【】 = "1234567890";


store.push_back(std::cref(str));


int a1val{42};


auto a1 = fmt::arg("a1", a1_val);


store.pushback(std::cref(a1));


// Changing str affects the output but only for string and custom types.


str【0】 = 'X';


std::string result = fmt::vformat("{} and {a1}");


assert(result == "X234567890 and 42");


  5.2.3)、push_back 函数原型:


template


void push_back(const detail::named_arg &arg)


  将命名参数添加到动态存储中,以便以后传递给格式化函数。std::reference_wrapper可以避免参数传递时的拷贝。


  5.2.4)、clear原型:


void clear()


  该函数将清除存储中的所有参数。


  5.2.5)、reserve函数原型:


void reserve(size_t new_cap, size_t new_cap_named)


  保留存储空间以至于能容纳new_cap参数,也包括new_cap_named 的命名参数。


  5.3)、class fmt::basic_format_args类


template


class fmt::basic_format_args


  格式化参数集合的视图。 为了避免生命周期的问题,它仅应在类型擦除的函数中用作参数类型,例如vformat函数:


void vlog(string_view format_str, format_args args); // OK


format_args args = make_format_args(42); // Error: dangling reference


  其公有函数:


  5.3.1)、basic_format_args重载:


template


basic_format_args(const format_arg_store &store)


  从format_arg_store 构造一个 basic_format_args 对象。


  5.3.2)、basic_format_args重载:


basic_format_args(const dynamic_format_arg_store &store)


  从 dynamic_format_arg_store 构造一个 basic_format_args 对象。


  5.3.3)、basic_format_args重载:


basic_format_args(const format_arg args, int count)


  根据一组动态参数构造一个basic_format_args对象。


  5.4)、format_arg 的get函数原型:


format_arg get(int id) const


  返回具有指定ID的参数。


  5.5)、结构体 fmt::format_args


  fmt::format_args是【basic_format_args】的别名,继承 fmt::basic_format_args


  5.6)、类 fmt::basic_format_arg:


template


class fmt::basic_format_arg


  6、兼容性


  类fmt::basic_string_view


template


class fmt::basic_string_view


  c++17以前, std::basic_string_view 的实现,其提供了一个子集的API


  fmt::basic_string_view 可以用来格式化字符串,即使std::string_view可以有效避免当使用与客户端代码不同的-std选项编译库时问题:


  公有函数:


  6.1)、basic_string_view重载


constexpr basic_string_view(const Char s, size_t count)


  根据C字符串和大小,构造一个字符串引用对象。


  6.2)、basic_string_view重载


basic_string_view(const Char s)


  从C字符串构造一个字符串引用对象,该字符串使用std :: char_traits :: length计算大小。


  6.3)、basic_string_view重载


template


basic_string_view(const std::basic_string &s)


  从std :: basic_string对象构造一个字符串引用。


  6.4)、data原型:


constexpr const Char data() const


  返回指向字符串数据的指针。


  6.5)、size


constexpr size_t size() const


  返回字符串的大小


  该类提供了对宽字符的支持


using fmt::string_view = typedef basic_string_view[span style="color: rgba(0, 0, 255, 1)">char

using fmt::wstring_view = typedef basic_string_view


  7、本地化


  默认情况下,所有格式化与语言环境无关。使用'n'格式,从本地语言环境中插入适当的数字分隔符,例如:


#include


#include


std::locale::global(std::locale("en_US.UTF-8"));


auto s = fmt::format("{:L}", 1000000); // s == "1,000,000"


C、format API#


  fmt/format.h定义了完整格式化的API,提供了编译时格式字符串检查,宽字符串,输出迭代器和用户定义的类型支持。


  内置格式和字符串类型以及格式定义专长中具有constexpr解析函数的用户定义类型均支持编译时检查。


  1、FMT_STRING(s)


  从字符串常量s构造一个编译时格式字符串。例如:


// A compile-time error because 'd' is an invalid specifier for strings.


std::string s = fmt::format(FMT_STRING("{:d}"), "foo");


  2、格式化用户定义的类型


  要创建用户定义的类型格式表,请专门设置formatter 结构模板并实现解析和格式化方法:


#include


struct point { double x, y; };


template


struct fmt::formatter


{


// Presentation format: 'f' - fixed, 'e' - exponential.


char presentation = 'f';


// Parses format specifications of the form 【'f' | 'e'】.


constexpr auto parse(format_parse_context& ctx) {


// auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) // c++11


// 【ctx.begin(), ctx.end()) is a character range that contains a part of


// the format string starting from the format specifications to be parsed,


// e.g. in


//


// fmt::format("{:f} - point of interest", point{1, 2});


//


// the range will contain "f} - point of interest". The formatter should


// parse specifiers until '}' or the end of the range. In this example


// the formatter should parse the 'f' specifier and return an iterator


// pointing to '}'.


// Parse the presentation format and store it in the formatter:


auto it = ctx.begin(), end = ctx.end();


if (it != end && (it == 'f' || it == 'e')) presentation = it++;


// Check if reached the end of the range:


if (it != end && it != '}')


throw format_error("invalid format");


// Return an iterator past the end of the parsed range:


return it;


}


// Formats //代码效果参考:http://www.jhylw.com.cn/183030045.html

the point p using the parsed format specification (presentation)

// stored in this formatter.


template


auto format(const point& p, FormatContext& ctx) {


// auto format(const point &p, FormatContext &ctx) -> decltype(ctx.out()) // c++11


// ctx.out() is an output iterator to write to.


return format_to(


ctx.out(),


presentation == 'f' ? "({:.1f}, {:.1f})" : "({:.1e}, {:.1e})",


p.x, p.y);


}


};


  然后,传递指针对象给任何函数:


point p = {1, 2};


std::string s = fmt::format("{:f}", p);


// s == "(1.0, 2.0)"


  还可以通过继承或组合来重用现有的格式化器,例如:


enum class color {red, green, blue};


template struct fmt::formatter: formatter


{


// parse is inherited from formatter.


template


auto format(color c, FormatContext& ctx)


{


string_view name = "unknown";


switch (c)


{


case color::red: name = "red"; break;


case color::green: name = "green"; break;


case color::blue: name = "blue"; break;


}


return formatter::format(name, ctx);


}


};


  由于解析是从formatter 继承的,因此它将识别所有字符串格式规范,例如:


fmt::format("{:>10}", color::blue)


  这行代码将会返回一个字符串:" blue"。


  可以为类的层次结构编写格式化器:


#include


#include


struct A


{


virtual ~A() {}


virtual std::string name() const { return "A"; }


};


struct B : A


{


virtual std::string name() const { return "B"; }


};


template


struct fmt::formatter

fmt::formatter

{


template

相关文章
|
5天前
|
人工智能 自然语言处理 API
解锁 DeepSeek API 接口:构建智能应用的技术密钥
在数字化时代,智能应用蓬勃发展,DeepSeek API 作为关键技术之一,提供了强大的自然语言处理能力。本文详细介绍 DeepSeek API,并通过 Python 请求示例帮助开发者快速上手。DeepSeek API 支持文本生成、问答系统、情感分析和文本分类等功能,具备高度灵活性和可扩展性,适用于多种场景。示例展示了如何使用 Python 调用 API 生成关于“人工智能在医疗领域的应用”的短文。供稿者:Taobaoapi2014。
|
6月前
|
监控 安全 测试技术
深入理解后端技术中的API设计原则
在当今数字化时代,后端技术已成为构建高效、可扩展和安全应用程序的关键因素。本文将探讨后端开发中的API设计原则,包括RESTful架构、版本控制以及安全性等方面,旨在帮助开发者提升API设计的质量和用户体验。通过对这些原则的深入理解,可以更好地满足业务需求并提高系统的可靠性。
90 0
|
2月前
|
XML 算法 API
通过亚马逊产品广告API获取国际商品详情的技术实现
本文详细介绍如何通过亚马逊产品广告API获取国际商品信息。首先,需注册亚马逊联盟账户并申请API访问权限,获取AWS Access Key ID等凭证。接着,解析API端点和服务,如ItemLookup和ItemSearch。然后,构建API请求,包括URL、参数设置及签名生成。以Python为例,使用requests或boto3库实现API调用,并处理XML格式的API响应。最后,注意API速率限制、区域设置、数据更新及错误处理。参考官方文档确保调用准确性和安全性。
|
3月前
|
JSON 搜索推荐 API
拍立淘API是基于图像识别技术的服务接口,支持淘宝、1688和义乌购平台。
拍立淘API是基于图像识别技术的服务接口,支持淘宝、1688和义乌购平台。用户上传图片后,系统能快速匹配相似商品,提供精准搜索结果,并根据用户历史推荐个性化商品,简化购物流程。开发者需注册账号并获取API Key,授权权限后调用接口,返回商品详细信息如ID、标题、价格等。使用时需遵守频率限制,确保图片质量,保障数据安全。
|
5月前
|
安全 物联网 API
API技术之身份认证
【10月更文挑战第17天】身份认证是API安全的核心,确保API可信可控。
API技术之身份认证
|
5月前
|
JSON 前端开发 测试技术
API接口 |产品经理一定要懂的10%技术知识
作为产品经理,掌握约10%的技术知识对处理API相关工作至关重要。这包括理解API的基本概念及其作为数据交换的桥梁作用;熟悉JSON和XML两种主要数据格式及其特点;了解常见HTTP请求方法(GET、POST、PUT、DELETE)及响应状态码;关注API安全性,如认证授权和数据加密;掌握API版本管理和错误处理技巧;重视性能优化,以提升用户体验;参与API联调测试,确保稳定可靠;并与前后端团队紧密协作,选择合适的第三方API服务,推动产品高效开发。
|
5月前
|
XML API 网络架构
API协议 的十种技术特点及适用场景
本文介绍了十种常见的API协议技术,包括REST、GraphQL、gRPC、SOAP、WebSocket、AMF和XML-RPC等,每种技术都有其特点和适用场景,如REST适用于轻量级Web服务开发,gRPC适合高性能分布式系统,而WebSocket则适用于需要低延迟交互的应用。
|
5月前
|
SQL Java API
深入探索Java的持久化技术——JPA(Java Persistence API)
【10月更文挑战第10天】深入探索Java的持久化技术——JPA(Java Persistence API)
206 0
|
5月前
|
Java API 数据库
深入探索Java的持久化技术——JPA(Java Persistence API)
【10月更文挑战第10天】深入探索Java的持久化技术——JPA(Java Persistence API)
150 0
|
5月前
|
安全 NoSQL 测试技术
商品详情API接口的技术实现
本文介绍了电商平台上商品详情API接口的设计与实现过程,涵盖需求分析、接口定义、数据模型设计及技术选型等方面。通过合理的后端框架、数据库设计和安全措施,确保接口高效、稳定和安全。最后,通过详尽的测试与部署步骤,实现优质购物体验。旨在为技术人员提供实用参考。

热门文章

最新文章