Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C+中记录用户定义的POD结构+; 我需要向传统C++项目添加日志记录,其中包含数百个用户定义的结构/类。这些结构仅包含主要类型,如int,float,char[],enum_C++_Logging_Serialization_Reflection - Fatal编程技术网

如何在C+中记录用户定义的POD结构+; 我需要向传统C++项目添加日志记录,其中包含数百个用户定义的结构/类。这些结构仅包含主要类型,如int,float,char[],enum

如何在C+中记录用户定义的POD结构+; 我需要向传统C++项目添加日志记录,其中包含数百个用户定义的结构/类。这些结构仅包含主要类型,如int,float,char[],enum,c++,logging,serialization,reflection,C++,Logging,Serialization,Reflection,需要记录对象的内容,最好是以人类可读的方式,但不是必须的,只要对象可以重建 除了为每个类编写不同的序列化方法外,还有其他方法吗 >由于C++没有反射,所以无法在运行时动态检查对象的成员。因此,您需要为每种类型编写特定的序列化/流式处理/日志记录函数 如果所有不同的类型都有同名成员,那么你可以编写一个模板函数来处理它们,但是我假设不是这样。< P>因为C++没有反射,所以你无法在运行时动态检查对象的成员。因此,您需要为每种类型编写特定的序列化/流式处理/日志记录函数 如果所有不同的类型都有同名成员

需要记录对象的内容,最好是以人类可读的方式,但不是必须的,只要对象可以重建


除了为每个类编写不同的序列化方法外,还有其他方法吗

>由于C++没有反射,所以无法在运行时动态检查对象的成员。因此,您需要为每种类型编写特定的序列化/流式处理/日志记录函数


如果所有不同的类型都有同名成员,那么你可以编写一个模板函数来处理它们,但是我假设不是这样。

< P>因为C++没有反射,所以你无法在运行时动态检查对象的成员。因此,您需要为每种类型编写特定的序列化/流式处理/日志记录函数


如果所有不同的类型都有同名成员,那么你可以编写一个模板函数来处理它们,但是我假设不是这样。

< P>因为C++没有反射,这不是那么容易。 如果要避免冗长的解决方案,可以使用可变模板

例如。 `类MyStruct{ 私人: INTA; 浮动f

公众: 无效日志() { 日志字段(a、f); } };`


其中log_fields()是可变模板。对于那些用户定义类型的所有基本类型也需要专门化,也需要递归的情况。

< P>因为C++没有反射,这不是那么容易。 如果要避免冗长的解决方案,可以使用可变模板

例如。 `类MyStruct{ 私人: INTA; 浮动f

公众: 无效日志() { 日志字段(a、f); } };`

其中log_fields()是可变模板。它需要专门用于在这些用户定义的类型上找到的所有基本类型以及递归情况。

您需要的是一个。这些工具可以读取源代码,构建表示源代码的编译器数据结构(通常是AST),并允许您修改AST和从修改后的AST重新生成源代码

这些是有用的,因为它们“走出”了语言,因此对您可以分析或转换的内容没有语言限制。因此,如果你的语言没有对一切进行反思,这并不重要;一个好的PTS将使您能够完全访问该语言的每个细节,包括注释和数字文本基数等奥秘

某些PTSE特定于目标语言(例如,“Jackpot”仅适用于Java)。一个真正好的PTS提供了一个任意编程语言的描述,然后可以操作该语言。该描述必须使PTS能够解析代码、分析代码(至少构建符号表)并预打印解析/修改的结果

好的PTSE将允许您编写要使用源到源转换进行的修改。这些规则规定了大致以以下形式编写的更改:

   if you see *this*, replace it by *that* when *condition*
其中,this和that是使用正在处理的目标语言语法的模式,condition是谓词(test),必须为true才能应用规则。这些模式表示格式良好的代码片段,通常允许元变量表示任意子片段的占位符

您可以将PTSE用于各种各样的程序操作任务。对于OP来说,他想要的是枚举程序中的所有结构,选择感兴趣的子集,然后为每个选定的结构生成一个序列化程序,作为对原始程序的修改

对于这个特定的任务,PTS必须能够解析和解析解析(构建符号表)C++。很少有工具可以做到这一点:Clang、我们的DMS软件再工程工具包和Rose编译器

使用DMS的解决方案如下所示:

domain Cpp~GCC5;  -- specify the language and specific dialect to process

pattern log_members( m: member_declarations ): statements = TAG;
      -- declares a marker we can place on a subtree of struct member declarations

rule serialize_typedef_struct(s: statement, m: member_declarations, i: identifier):
           statements->statements
   = "typedef struct { \m } \i;" -> 
     "typedef struct { \m } \i;
      void \make_derived_name\(serialize,\i) ( *\i argument, s: stream )
          { s << "logging" << \toString\(\i\);
            \log_members\(\m\)
          }"
      if selected(i); -- make sure we want to serialize this one

rule generate_member_log_list(m: member_declarations, t: type_specification, n: identifier): statements -> statements
   " \log_members\(\t \n; \m\)" -> " s << \n; \log_members\(\m\) ";

rule generate_member_log_base(t: type_specification, n: identifier): statements -> statements
   " \log_members\(\t \n; \)" -> " s << \n; ";

ruleset generate_logging {
   serialize_typedef struct,
   generate_member_log_list,
   generate_member_log_base 
}
域Cpp~GCC5;——指定要处理的语言和特定方言
模式日志成员(m:成员声明):statements=TAG;
--声明可以放置在结构成员声明子树上的标记
规则序列化_typedef_结构(s:语句,m:成员声明,i:标识符):
语句->语句
=“typedef结构{\m}\i;”->
“类型定义结构{\m}\i;
void\make\u派生的\u name\(序列化,\i)(*\i参数,s:stream)
{s您需要的是一个。这些工具可以读取源代码,构建表示源代码的编译器数据结构(通常是AST),并允许您修改AST并从修改后的AST重新生成源代码

这些是有用的,因为它们“走出去”“语言,因此没有语言对您可以分析或转换的内容施加限制。因此,如果您的语言没有对所有内容的反映,这并不重要;好的PTS将让您完全了解语言的每一个细节,包括注释和数字文字基等奥秘

一些PTS特定于目标语言(例如,“Jackpot”仅适用于Java)。一个真正好的PTS提供了对任意编程语言的描述,然后可以操作该语言。该描述必须使PTS能够解析代码、分析代码(至少构建符号表)并对解析/修改后的结果进行预打印

好的PTSE将允许您使用源代码到源代码的转换编写您想要进行的修改。这些规则指定了大致以以下形式编写的更改:

   if you see *this*, replace it by *that* when *condition*
其中,这和那是使用正在处理的目标语言语法的模式,以及condi