C++ 在实现自定义类型的格式化程序时,如何有效地转发格式化参数
我正在尝试编写一个自定义格式化程序来帮助我打印向量。我试图维护格式说明符,以便向量中的每个项都以相同的方式格式化 我的大部分灵感都来自于 复制格式字符串只是为了将其反馈给另一个C++ 在实现自定义类型的格式化程序时,如何有效地转发格式化参数,c++,fmt,custom-formatting,C++,Fmt,Custom Formatting,我正在尝试编写一个自定义格式化程序来帮助我打印向量。我试图维护格式说明符,以便向量中的每个项都以相同的方式格式化 我的大部分灵感都来自于 复制格式字符串只是为了将其反馈给另一个fmt::format调用,这似乎过于笨拙和低效,特别是当扩展类:fmt::formatter已经在内部为我们提供了一个完全有效的解析函数时,(我在本例中重新实现了它,只是为了以一种黑客的方式获得所需的输出) 我真的想删除自定义解析实现并替换该行 format_to(out, formatString, item); 与
fmt::format
调用,这似乎过于笨拙和低效,特别是当扩展类:fmt::formatter
已经在内部为我们提供了一个完全有效的解析
函数时,(我在本例中重新实现了它,只是为了以一种黑客的方式获得所需的输出)
我真的想删除自定义解析实现并替换该行
format_to(out, formatString, item);
与
format_to(out,fmt::formatter::format(项,上下文))
除非它无效/无法编译
正确的方法是什么
注意:我完全意识到在我的示例中扩展类型是毫无意义的,我可以将它作为局部变量,但是我尝试重用类的功能,因此扩展它感觉是正确的方向,即使我还没有找到解决方案
我发现的所有其他示例的列表对我没有帮助:
- (仅适用于直接向超级实现返回单个调用,但不需要重新实现解析或创建新的格式字符串)
- (放弃格式化或需要手动重新实现格式化)
- (几乎是我想要的,但仍然创建一个新的格式字符串,而不是重用用户最初指定的格式字符串)
- (同样,建议重新实现parse函数,并使用新的格式字符串调用
,尽管调用方已经指定了一个格式字符串,并且存在该类型的现有解析函数……)格式
解析
实现,使用继承的函数,在格式中使用fmt::formatter::format(item,context)
输出每个项():
#包括
#包括
模板
结构fmt::格式化程序:fmt::格式化程序
{
模板
自动格式化(const std::vector和container、FormatContext和context)
{
auto&&out=context.out();
格式_to(out,“{”);
bool first=true;
用于(常量自动和项目:容器){
如果(第一){
第一个=假;
}否则{
格式为(输出,“,”);
}
fmt::formatter::format(项、上下文);
}
将格式_返回到(out,“}”);
}
};
int main()
{
fmt::print(“{.3f}\n”,std::vector{0.01321.123654398.4328,-0.0000000000123452374651273.7236457862345});
fmt::print(“{.1e}\n”,std::vector{0.01321.123654398.4328,-0.0000000000123452374651273.7236457862345});
返回0;
}
您可以在下面的文档中看到此模式的其他示例。我真是个白痴!当然fmt::formatter::format(item,context);
正在将其文本添加到out
变量中!我希望它返回字符串或其他东西……我讨厌auto
对程序员隐藏了多少内容,这使得如何使用东西变得困难!
{0.000, 321.123, 654398.433, -0.000, 2374651273.724}
{0.0e+00, 3.2e+02, 6.5e+05, -1.2e-12, 2.4e+09}
format_to(out, formatString, item);
format_to(out, fmt::formatter<ValueType>::format(item, context))
#include <fmt/core.h>
#include <fmt/format.h>
template<typename ValueType>
struct fmt::formatter<std::vector<ValueType>> : fmt::formatter<ValueType>
{
template <typename FormatContext>
auto format(const std::vector<ValueType>& container, FormatContext& context)
{
auto&& out = context.out();
format_to(out, "{{");
bool first = true;
for (const auto& item : container) {
if (first) {
first = false;
} else {
format_to(out, ", ");
}
fmt::formatter<ValueType>::format(item, context);
}
return format_to(out, "}}");
}
};
int main()
{
fmt::print("{:.3f}\n", std::vector{ 0.0, 321.123, 654398.4328, -0.0000000000012345, 2374651273.7236457862345});
fmt::print("{:.1e}\n", std::vector{ 0.0, 321.123, 654398.4328, -0.0000000000012345, 2374651273.7236457862345});
return 0;
}