fmt的API介绍

本文翻译: https://fmt.dev/latest/api.html 

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

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

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 <fmt/core.h>

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

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

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

#include <fmt/core.h>
fmt::print("Elapsed time: {0:.2f} seconds", 1.23);

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

template <typename S, typename... Args, typename Char = char_t<S>>
void fmt::print(std::FILE *f, const S &format_str, Args&&... args)

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

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

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

template <typename Char, typename T>
detail::named_arg<Char, T> 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 <typename Context = format_context, typename... Args>
format_arg_store<Context, Args...> fmt::make_format_args(const Args&... args)

    构造一个format_arg_store对象,该对象包含对参数的引用,并且可以隐式转换为format_args。可以省略上下文,在这种情况下,它默认为上下文。
有关生命周期的考虑,请参见arg()。

  

  5.2)、class fmt::format_arg_store类

template <typename Context, typename... Args>    
class fmt::format_arg_store

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

  fmt::format_arg_store 的公有函数:

  5.2.1)、push_back函数原型

template <typename T>
void push_back(const T &arg)

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

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

fmt::dynamic_format_arg_store<fmt::format_context> 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 <typename T>
void push_back(std::reference_wrapper<T> arg)

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

fmt::dynamic_format_arg_store<fmt::format_context> store;
char str[] = "1234567890";
store.push_back(std::cref(str));
int a1_val{42};
auto a1 = fmt::arg("a1_", a1_val);
store.push_back(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 <typename T>
void push_back(const detail::named_arg<char_type, T> &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 <typename Context>
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 <typename... Args>
basic_format_args(const format_arg_store<Context, Args...> &store)

  从format_arg_store 构造一个 basic_format_args 对象。

  

  5.3.2)、basic_format_args重载:

basic_format_args(const dynamic_format_arg_store<Context> &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<context>】的别名,继承 fmt::basic_format_args< format_context >

  5.6)、类 fmt::basic_format_arg:

template <typename Context>
class fmt::basic_format_arg

  6、兼容性

  类fmt::basic_string_view

template <typename Char>
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 <Char> :: length计算大小。

  6.3)、basic_string_view重载

template <typename Traits, typename Alloc>
basic_string_view(const std::basic_string<Char, Traits, Alloc> &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<char>
using fmt::wstring_view     = typedef basic_string_view<wchar_t>    

  

  7、本地化

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

#include <fmt/core.h>
#include <locale>

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 <T>结构模板并实现解析和格式化方法:

#include <fmt/format.h>

struct point { double x, y; };

template <>
struct fmt::formatter<point> {
  // 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 the point p using the parsed format specification (presentation)
  // stored in this formatter.
  template <typename FormatContext>
  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<color>: formatter<string_view> 
{
  // parse is inherited from formatter<string_view>.
  template <typename FormatContext>
  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<string_view>::format(name, ctx);
  }
};

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

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

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

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

#include <type_traits>
#include <fmt/format.h>

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

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

template <typename T>
struct fmt::formatter<T, std::enable_if_t<std::is_base_of<A, T>::value, char>> :
    fmt::formatter<std::string> 
    {
      template <typename FormatCtx>
      auto format(const A& a, FormatCtx& ctx)
      {
        return fmt::formatter<std::string>::format(a.name(), ctx);
      }
};

int main(int argc, char * argv[]) 
{
  B b;
  A& a = b;
  fmt::print("{}", a); // prints "B"
  
  return 0;
}    

  3、basic_format_parse_context类

template <typename Char, typename ErrorHandler = detail::error_handler>
class fmt::basic_format_parse_context

  解析上下文,由解析的格式字符串范围和用于自动索引的参数计数器组成。

  可以将一下类型取别名,用于常见字符类型

Type                    Definition
format_parse_context    basic_format_parse_context<char>
wformat_parse_context    basic_format_parse_context<wchar_t>

  basic_format_parse_context类类继承: fmt::detail::error_handler

  公有函数:

    3.1)、begin

constexpr iterator begin() const

    返回一个迭代器,指向要解析的格式字符串范围的开头

    3.2)、end

constexpr iterator end() const

    返回一个迭代器,指向要解析的格式字符串范围的结束

    3.3)、advance_to

void advance_to(iterator it)

    将迭代器前进到it

    3.4)、next_arg_id

int next_arg_id()

    如果使用手动参数索引,则报告错误;否则返回下一个参数索引并切换到自动索引。

    3.5)、check_arg_id

void check_arg_id(int)

    如果使用自动参数索引,则报告错误;否则切换到手动索引。

D、支持输出迭代器

  1、

template <typename OutputIt, typename S, typename... Args>
OutputIt fmt::format_to(OutputIt out, const S &format_str, Args&&... args)

  格式化参数,将结果写入输出迭代器,并返回超出输出范围末尾的迭代器。 例如:

std::vector<char> out;
fmt::format_to(std::back_inserter(out), "{}", 42);

  2、

template <typename OutputIt, typename S, typename... Args>
format_to_n_result<OutputIt> fmt::format_to_n(OutputIt out, size_t n, const S &format_str, const Args&... args)

  格式化参数,将结果的n个字符写到输出迭代器中,并返回总输出大小和迭代器。

  3、结构体:fmt::format_to_n_result

template <typename OutputIt>
struct fmt::format_to_n_result

  公有成员:

    3.1)、OutputIt out
      迭代器指向末尾
    3.2)、size_t size
      总(未截断)输出大小。

E、Literal-based API

  fmt/format.h中定义了以下用户定义的Literal。

  1、

detail::udl_formatter<char> fmt::literals::operator""_format(const char *s, size_t n)

  用户定义的Litera等效于fmt :: format()。例如:

using namespace fmt::literals;
std::string message = "The answer is {}"_format(42);    

  2、

detail::udl_arg<char> fmt::literals::operator""_a(const char *s, size_t)

  用户定义的Litera等效于fmt :: argv()。 例如:

using namespace fmt::literals;
fmt::print("Elapsed time: {s:.2f} seconds", "s"_a=1.23);


F、实用工具(Utilities)

  1、fmt::is_char

template <typename T>
struct fmt::is_cha

  判断T是否为字符类型。 继承false_type

using fmt::char_t = typedef typename detail::char_t_impl<S>::type

  字符串的字符类型。

  

  2、 fmt::formatted_size

template <typename... Args>
size_t fmt::formatted_size(string_view format_str, const Args&... args)

  返回格式(format_str,args ...)的输出中的字符数。

  3、fmt::to_string

template <typename T>
std::string fmt::to_string(const T &value)

  使用类型T的默认格式将value转换为std :: string。例子:

#include <fmt/format.h>
std::string answer = fmt::to_string(42);

  

  4、 fmt::to_wstring

template <typename T>
std::wstring fmt::to_wstring(const T &value)

  使用类型T的默认格式将value转换为std :: wstring。

  5、 fmt::to_string_view

template <typename Char>
basic_string_view<Char> fmt::to_string_view(const Char *s)

  返回参数S的字符串view.为了向{fmt}添加自定义字符串类型支持,重载了函数:to_string_view。例如:

namespace my_ns 
{
    inline string_view to_string_view(const my_string& s) 
    {
      return {s.data(), s.length()};
    }
}
std::string message = fmt::format(my_string("The answer is {}"), 42);

  6、fmt::join

template <typename Range>
arg_join<detail::iterator_t<const Range>, detail::sentinel_t<const Range>, char> fmt::join(const Range &range, string_view sep)    

  返回一个对象,该对象的格式设置range用sep分隔的元素。例如:

std::vector<int> v = {1, 2, 3};
fmt::print("{}", fmt::join(v, ", "));
// Output: "1, 2, 3"

  fmt :: join将传递的格式说明符应用于range元素:

fmt::print("{:02}", fmt::join(v, ", "));
// Output: "01, 02, 03"

  7、fmt::join

template <typename It, typename Sentinel>
arg_join<It, Sentinel, char> fmt::join(It begin, Sentinel end, string_view sep

  返回一个对象,该对象使用由sep分隔,格式化迭代器范围[begin,end)。

  8、类 fmt::detail::buffer

  具有可选增长能力的连续内存缓冲区。它是一个内部类,不应该直接使用,通过 basic_memory_buffer 访问

  公有函数:

    8.1)、size

size_t size() const

      返回缓冲区的大小

    8.2)、capacity

size_t capacity() const

      返回此缓冲区的容量

    8.3)、data

T *data()

      返回一个指向该缓冲区的指针,指针类型与模板T有关

    8.4)、resize

void resize(size_t new_size)

      调整缓冲区大小。如果T是POD类型,则可能不会初始化新元素。

    8.5)、clear

void cLear()

      清空buffer

    8.6)、reserve

void reserve(size_t new_capacity)

      保留至少能够存储 new_capacity的元素空间

    8.7)、append

template <typename U>
void append(const U *begin, const U *end)

      向buffer的末尾追加数据

  9、fmt::basic_memory_buffer类

  动态增长的内存缓冲区,用于带有可存储在对象本身中的第一个SIZE元素的类型。

  将以下类型别名,用于常见字符类型:

Type            Definition
memory_buffer    basic_memory_buffer<char>
wmemory_buffer    basic_memory_buffer<wchar_t>

  例如:

fmt::memory_buffer out;
format_to(out, "The answer is {}.", 42);

  字符串将输出到out:

The answer is 42.

  

  可以使用to_string(out)将输出转换为std :: string。
  该类继承 fmt::detail::buffer< T >

  公有函数:

    9.1)、basic_memory_buffer

basic_memory_buffer(basic_memory_buffer &&other)

      构造一个fmt :: basic_memory_buffer对象,将另一个对象的内容移动到该对象。

    9.2)、basic_memory_buffer

basic_memory_buffer &operator=(basic_memory_buffer &&other)

      重载运算符,将对象other的值拷贝到当前对象

   受保护函数:

    9.3)、grow

void grow(size_t capacity)    

      扩张buffer的容量以便能容纳当前元素数量。

G、系统错误

  fmt不使用errno向用户传达错误。但它可调用设置errno的系统函数errno。用户不应对库函数保留的errno值做任何臆测。

  1、类fmt::system_error

class fmt::system_error

  操作系统或语言运行时返回的错误,例如:文件打开的错误。该类继承runtime_error。

  公有函数:

    1.1)、system_error

template <typename... Args>
system_error(int error_code, string_view message, const Args&... args)    

      构造一个fmt :: system_error对象,其格式为fmt :: format_system_error(),消息和传递给构造函数的参数将会自动被格式化,类似:fmt::format()。例如:

// This throws a system_error with the description
//   cannot open file 'madeup': No such file or directory
// or similar (system message may vary).
const char *filename = "madeup";
std::FILE *file = std::fopen(filename, "r");
if (!file)
  throw fmt::system_error(errno, "cannot open file '{}'", filename);

   2、fmt::format_system_error函数

void fmt::format_system_error(detail::buffer<char> &out, int error_code, string_view message)

  格式化由操作系统或语言运行时返回的错误,例如文件打开错误,例如,以下形式输出:

<message>: <system-message>

  其中,<message>是传递的消息,而<system-message>是与错误代码相对应的系统消息。error_code是errno给出的系统错误代码。如果error_code不是有效的错误代码(例如-1),则系统消息可能看起来像“未知错误-1”,并且取决于平台因素。

  3、类fmt::windows_error

  Windows错误类,继承fmt::system_error

    3.1)、public构造函数

template <typename... Args>
windows_error(int error_code, string_view message, const Args&... args)        

    创建一个 fmt::system_error的对象,对象的格式如下:

<message>: <system-message>    

    其中,<message>是格式化的消息,而<system-message>是与错误代码相对应的系统消息。error_code是GetLastError给出的Windows错误代码。如果error_code不是有效的错误代码(例如-1),则系统消息将看起来像“错误-1”。例如:

// This throws a windows_error with the description
//   cannot open file 'madeup': The system cannot find the file specified.
// or similar (system message may vary).
const char *filename = "madeup";
LPOFSTRUCT of = LPOFSTRUCT();
HFILE file = OpenFile(filename, &of, OF_READ);
if (file == HFILE_ERROR) 
{
  throw fmt::windows_error(GetLastError(),
                           "cannot open file '{}'", 
                           filename);
}    


H、定制分配器

  fmt库支持自定义动态内存分配。可以将自定义分配器类指定为fmt :: basic_memory_buffer的模板参数:

using custom_memory_buffer = fmt::basic_memory_buffer<char, fmt::inline_buffer_size, custom_allocator>;    

  也可以编写使用自定义分配器的格式化函数:

using custom_string =
  std::basic_string<char, std::char_traits<char>, custom_allocator>;

custom_string vformat(    custom_allocator alloc, 
                        fmt::string_view format_str,
                        fmt::format_args args) 
{
  custom_memory_buffer buf(alloc);
  fmt::vformat_to(buf, format_str, args);
  return custom_string(buf.data(), buf.size(), alloc);
}

template <typename ...Args>
inline custom_string format(custom_allocator alloc,
                            fmt::string_view format_str,
                            const Args& ... args) 
{
  return vformat(alloc, format_str, fmt::make_format_args(args...));
}

  分配器将仅用于输出容器。如果使用命名参数,则将使用默认分配器分配存储指向它们的指针的容器。浮点格式还取决于可以进行分配的sprintf。

 

I、范围和元组的格式化

  该库还支持范围和元组的便捷格式化, 例如:

#include <fmt/ranges.h>

std::tuple<char, int, float> t{'a', 1, 2.0f};
// Prints "('a', 1, 2.0)"
fmt::print("{}", t);        

  

  注意: 当前的使用的是头文件format.h中的fmt::join函数。

  当使用 fmt::join时,可以使用自定义的分隔符将元组的元素分开:

#include <fmt/ranges.h>

std::tuple<int, char> t = {1, 'a'};
// Prints "1, a"
fmt::print("{}", fmt::join(t, ", "));    

J、时间和日期的格式化

  fmt还支持对时间和日期的格式化处理。

#include <fmt/chrono.h>
std::time_t t = std::time(nullptr);
// Prints "The date is 2016-04-29." (with the current date)
fmt::print("The date is {:%Y-%m-%d}.", fmt::localtime(t));

  格式化字符串的语法,具体可以 查看后面的链接: https://en.cppreference.com/w/cpp/chrono/c/strftime

K、编译时格式化字符串

  fmt/compile.h提供格式字符串编译支持。格式字符串在编译时进行解析,并转换为有效的格式代码。支持内置和字符串类型的参数,以及格式设置专长中具有constexpr解析函数的用户定义类型的参数。与默认API相比,格式字符串编译可以生成更多的二进制代码,仅在格式化是性能瓶颈的地方才建议使用。


  FMT_COMPILE(s)
  
将字符串文字s转换为格式字符串,该格式字符串将在编译时进行解析,并转换为有效的格式代码。如果编译器支持,则需要C ++ 17 constexpr。例如:

// Converts 42 into std::string using the most efficient method and no
// runtime format string processing.
std::string s = fmt::format(FMT_COMPILE("{}"), 42);

L、标准输出流std::ostream 的支持

  fmt/ostream.h提供std :: ostream支持,包括格式化运算符<<的用户定义类型的格式。例如:

include <fmt/ostream.h>

class date 
{
  int year_, month_, day_;
public:
  date(int year, int month, int day): year_(year), month_(month), day_(day) {}

  friend std::ostream& operator<<(std::ostream& os, const date& d) 
  {
    return os << d.year_ << '-' << d.month_ << '-' << d.day_;
  }
};

std::string s = fmt::format("The date is {}", date(2012, 12, 9));
// s == "The date is 2012-12-9"

  1、 fmt::print

template <typename S, typename... Args, typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
void fmt::print(std::basic_ostream<Char> &os, const S &format_str, Args&&... args)    

  将格式化的数据输出到标准输出流os。例如:

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

M、printf的格式化

  头文件fmt / printf.h提供类似printf的格式化功能。以下函数使用带有POSIX扩展名的printf格式字符串语法来表示位置参数。与标准对等函数不同,fmt函数具有类型安全性,如果参数类型与其格式规范不匹配,则抛出异常。

  1、fmt::printf

template <typename S, typename... Args>
int fmt::printf(const S &format_str, const Args&... args)

  将格式化的数据输出到stdout。例如:

fmt::printf("Elapsed time: %.2f seconds", 1.23);

  2、fmt::fprintf

template <typename S, typename... Args, typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
int fmt::fprintf(std::FILE *f, const S &format, const Args&... args)

  将格式化的数据输出到文件。例如:

fmt::fprintf(stderr, "Don't %s!", "panic");

  3、fmt::fprintf

template <typename S, typename... Args, typename Char = char_t<S>>
int fmt::fprintf(std::basic_ostream<Char> &os, const S &format_str, const Args&... args)

  将数据输出到os。 例如:

fmt::fprintf(cerr, "Don't %s!", "panic");

  4、fmt::sprintf

template <typename S, typename... Args, typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
std::basic_string<Char> fmt::sprintf(const S &format, const Args&... args)

  格式化参数,并返回一个已经格式化的字符串。例如:

std::string message = fmt::sprintf("The answer is %d", 42);

N、兼容c++20的std::format
  fmt几乎实现了所有c++20中格式化库,但有几点不同:
    1、命名空间的不同,fmt的函数全部都在fmt的命名空间下,避免了与std命名空间下的函数同名冲突。
    2、当前的fmt库中,'L'仍然不能用做格式化符连接使用。
    3、宽度计算不使用字素聚类。后者已在单独的分支中实施,但尚未集成。
    4、计时格式不支持C ++ 20日期类型,因为它们不是标准库实现提供的。

--------------------------------------完--------------------------------------------------

 githu是个好地方,人富水也甜。 

欢迎指正

猜你喜欢

转载自www.cnblogs.com/pandamohist/p/13364900.html