C++ 在C++;{fmt}?

C++ 在C++;{fmt}?,c++,reflection,fmt,C++,Reflection,Fmt,在我当前的项目中,我需要一个定制的非常简单的“序列化”表示法来表示几个普通的数据传输对象(DTO)结构。在第一次提出一个定制的解决方案之后,这是一个很大的PITA,我有了使用{fmt}的想法 所以,在过去的几天里,我通过扩展fmt::formatter模板专门化机制来处理自定义类型的格式。因此,他们非常有帮助 在做了一点修改之后,我提出了一个非常通用的poc解决方案,它允许以多种自定义格式格式化结构,看起来有点像以下内容: struct Inner { double x; std

在我当前的项目中,我需要一个定制的非常简单的“序列化”表示法来表示几个普通的数据传输对象(DTO)结构。在第一次提出一个定制的解决方案之后,这是一个很大的PITA,我有了使用{fmt}的想法

所以,在过去的几天里,我通过扩展
fmt::formatter
模板专门化机制来处理自定义类型的格式。因此,他们非常有帮助

在做了一点修改之后,我提出了一个非常通用的poc解决方案,它允许以多种自定义格式格式化结构,看起来有点像以下内容:

struct Inner {
    double x;
    std::string y;
    int z;
};
struct Outer {
    int a;
    std::string b;
    Inner inner;
};

template<>
struct reflection<Outer> {
    /*definition of class name and field names has to be provided manually...*/
};

template<>
struct reflection<Inner> {
    /*definition of class name and field names has to provided manually...*/
};

/*
...
couple dozend lines of meta programming and fmt::formatter specializations.
...
*/

auto outer = Outer{.a=1,.b="hello",.inner={.x=3.12,.y=" ",.z=2}};

std::string simple = fmt::format("{:s}", outer); // :s means format as simple
assert(simple == "a|hello|3.12| |2");
assert(fmt::format("{:s;}", outer) == "a;hello;3.12; ;2");

std::string  extended = fmt::format("{:e}",outer); // :e means format as extended
assert(extended == "Outer{.a=1, .b=hello, .inner=Inner{.x=3.12, .y= , .z=2}}");
结构内部{ 双x; std::字符串y; intz; }; 结构外部{ INTA; std::字符串b; 内在的; }; 模板 结构反射{ /*必须手动提供类名和字段名的定义*/ }; 模板 结构反射{ /*必须手动提供类名和字段名的定义*/ }; /* ... 元编程和fmt::格式化程序专门化的两行代码。 ... */ 自动外部=外部{.a=1,.b=“hello”,.inner={.x=3.12,.y=”“,.z=2}; std::string simple=fmt::format(“{:s}”,外部);/:s表示格式简单 断言(simple==“a | hello | 3.12 | 2”); 断言(fmt::format(“{:s;}”,外部)==“a;hello;3.12;2”); std::string extended=fmt::format(“{:e}”,外部);/:e表示扩展格式 断言(extended==“Outer{.a=1、.b=hello、.inner=internal{.x=3.12、.y=,.z=2}”); 显然,没有标准的方法来反映字段和结构名称,因此必须手动或通过宏magic提供反射结构。但这是另一个我不想在这里讨论的话题如果幸运的话,我们可以在c++23\o/中获得一些最小的编译时反射。让我们期待吧

我把这些放在一起

实际问题是:

将通过由{fMT}提供的简单反射API格式化用户定义的类型,是您认为将来可能扩展到{fMT}的东西吗? 我设想了一个场景,在这个场景中,预定义了几个琐碎的格式模式,用户只需为其类型提供反射

这样,我甚至可以看到格式化表达式,如
fmt::format(“{:json,prety,tabwith=4}”,outer)

另外,也许我只是在重新发明轮子,所以如果有类似的事情,基于{fmt}的话,告诉我!:)

无论如何,感谢您为社区提供了非常棒的工具,并祝贺您将其变成c++20

你好,马丁

将通过由{fMT}提供的简单反射API来格式化用户定义的类型,这是您认为将来可能扩展到{fMT} < /p>的东西。


可能,但它必须是一个显式的opt-in,也就是说,这样的类型不会以这种方式自动格式化,因为通常您需要更高级的表示,而不是字段集合。例如,您可能希望将点格式化为
(x,y)
,而不是
点{.x=x,.y=y}

数据代表什么?数据传输对象,例如,内部/域对象的表示,其唯一目的是将内部/域对象与某些序列化或数据库引擎集成。本质上是粘合代码:DI绝对同意。对于我目前试验的方法,它需要适当的include(类似于
#include
)和显式格式说明符(即
{:e}
{:foobar}
)才能工作。但是,后者仅在运行时检查(即,
fmt::print(“{}”,外部)
将在头存在但运行时失败时编译)-我必须对编译时格式字符串做进一步的实验,看看是否/如何在编译时验证显式格式字符串要求。我想我会继续实验:)如果我有一些我认为合理有用的东西,我会回来,可能会通过github直接与您联系!