如何在c++ format中实现格式化串和内容字段成对出现的功能

主要用于解决以下问题:

当要格式化的字段非常多时,格式化串中的{}也会非常多,如果{}中需要带修饰,则修饰的位置和字段的位置必须要正确匹配,下面的示例只包含10个字段,实际项目中的字段可能会达到50个以上,这就导致{}和字段要正确匹配这个工作靠人肉配对时会非常痛苦,如果字段还会经常增删,那问题就更严重;

之前的格式化代码:
userinfo u;

fmt::format(
	"{},{},{},{.2f},{},{},{},{},{},{}"
	, u.id
	, u.name
	, u.age
	, u.height
	, u.city
	, u.x
	, u.y
	, u.z
	, u.parent
	, u.mother
	);
之后的格式化代码

此时格式化串{}和字段是成对出现的,无论有多少字段,无论是否经常增删,写代码时都会非常轻松

userinfo u;

xformat(
	"{}", u.id
	"{}", u.name
	"{}", u.age
	"{.2f}", u.height
	"{}", u.city
	"{}", u.x
	"{}", u.y
	"{}", u.z
	"{}", u.parent
	"{}", u.mother
	);
具体实现如下:
#include <asio2/external/fmt.hpp>
#include <asio2/util/string.hpp>

template<class AllFmt, class Tuple, class FmtStr, class T, class... Args>
auto xformat_cat(AllFmt& allfmt, Tuple&& tup, FmtStr&& fmtstr, T&& val, Args&&... args)
{
	allfmt += std::forward<FmtStr>(fmtstr);

	if constexpr (sizeof...(Args))
	{
		return xformat_cat(allfmt,
			std::tuple_cat(std::forward<Tuple>(tup), std::tuple(std::forward<T>(val))),
			std::forward<Args>(args)...);
	}
	else
	{
		return std::tuple_cat(std::forward<Tuple>(tup), std::tuple(std::forward<T>(val)));
	}
}

template<class CharT, class Tuple, std::size_t... I>
auto xformat_do(std::basic_string<CharT>& allfmt, Tuple&& tup, std::index_sequence<I...>)
{
	if constexpr (std::is_same_v<CharT, wchar_t>)
	{
		return fmt::vformat(fmt::wstring_view(allfmt),
			fmt::make_wformat_args(std::get<I>(std::forward<Tuple>(tup))...));
	}
	else
	{
		return fmt::vformat(allfmt,
			fmt::make_format_args(std::get<I>(std::forward<Tuple>(tup))...));
	}
}

template<class CharT, class Tuple>
auto xformat_do(std::basic_string<CharT>& allfmt, Tuple&& tup)
{
	return xformat_do(allfmt, std::forward<Tuple>(tup),
		std::make_index_sequence<std::tuple_size_v<std::remove_cv_t<std::remove_reference_t<Tuple>>>>{});
}

template<class FmtStr, class T, class... Args>
auto xformat(FmtStr&& fmtstr, T&& val, Args&&... args)
{
	if constexpr (sizeof...(Args))
	{
		auto allfmt = asio2::to_basic_string(std::forward<FmtStr>(fmtstr));

		return xformat_do(allfmt, xformat_cat(allfmt,
			std::tuple(std::forward<T>(val)), std::forward<Args>(args)...));
	}
	else
	{
		return fmt::format(std::forward<FmtStr>(fmtstr), std::forward<T>(val));
	}
}

int main()
{
	std::string s1 = "abc", s2 = "def";
	std::wstring ws1 = L"abc", ws2 = L"def";

	std::cout << xformat("{}", std::move(s1), "{}", std::move(s2)) << std::endl;
	std::wcout << xformat(L"{}", std::move(ws1), L"{}", std::move(ws2)) << std::endl;

	while (std::getchar() != '\n');

	return 0;
}

最后更新于2023-08-04
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值