Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.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++:将控制台输出存储在宏中是否更好? 我刚开始学习C++的一些基础知识,但有两件事我已经意识到: 宏和函数的区别在于,宏是预处理的,而函数是事后编译的 在我读过的每一段代码中,也有一些定义了宏,但从来没有人为控制台输出定义过宏_C++_Macros_Cout - Fatal编程技术网

C++:将控制台输出存储在宏中是否更好? 我刚开始学习C++的一些基础知识,但有两件事我已经意识到: 宏和函数的区别在于,宏是预处理的,而函数是事后编译的 在我读过的每一段代码中,也有一些定义了宏,但从来没有人为控制台输出定义过宏

C++:将控制台输出存储在宏中是否更好? 我刚开始学习C++的一些基础知识,但有两件事我已经意识到: 宏和函数的区别在于,宏是预处理的,而函数是事后编译的 在我读过的每一段代码中,也有一些定义了宏,但从来没有人为控制台输出定义过宏,c++,macros,cout,C++,Macros,Cout,现在我的问题是,你应该做这样的事吗 没有宏: //... cout << "This is a test"; cout << "This is another test"; cout << "This is a third test" << " with two strings in one"; //.. 使用宏: #define OUTP(x) (cout << x) //... OUTP("This is a test"); O

现在我的问题是,你应该做这样的事吗

没有宏:

//...
cout << "This is a test";
cout << "This is another test";
cout << "This is a third test" << " with two strings in one";
//..
使用宏:

#define OUTP(x) (cout << x)

//...
OUTP("This is a test");
OUTP("This is another test");
OUTP("This is a third test" + " with two strings in one");
//...

首先,我看不出有什么大的区别,除了我不会对宏感到困惑,因为通常我使用宏作为输出。与常规输出相比,它具有某些优势,即:

您可以在一个位置更改所有输出-在宏定义处。例如,如果要在所有输出前加上时间戳,则使用宏时只需更改宏一次。 您可以引入输出级别,如调试、信息或错误。根据给定的输出级别(例如错误),将编译匹配的输出(例如错误和致命错误)并执行,所有其他不相关的输出(例如调试)甚至不会编译,也不会包含在二进制代码中。此外,许多IDE甚至会灰显不相关的代码行。
您还可以在宏中引入可变数量的输入参数、代码行号、编译日期和时间等。甚至在多线程输出中使用互斥,因为cout我使用宏进行输出。与常规输出相比,它具有某些优势,即:

您可以在一个位置更改所有输出-在宏定义处。例如,如果要在所有输出前加上时间戳,则使用宏时只需更改宏一次。 您可以引入输出级别,如调试、信息或错误。根据给定的输出级别(例如错误),将编译匹配的输出(例如错误和致命错误)并执行,所有其他不相关的输出(例如调试)甚至不会编译,也不会包含在二进制代码中。此外,许多IDE甚至会灰显不相关的代码行。
您还可以在宏中引入可变数量的输入参数、代码行号、编译日期和时间等。甚至在多线程输出中使用互斥,因为coutBetter是一个非常模糊的术语,它实际上取决于您试图实现什么

每个实施决策都有其优缺点,因此它实际上取决于单个项目

据我所见,在宏后面抽象输出的好处可能是:

交换输出方法的更简单方法,有利于在需要时使用更易于管理的日志结构 少打字 如果宏负责添加一些常用格式选项,则会更加统一 缺点可能是:

您将失去灵活性,因为宏将不可避免地不允许直接使用cout所允许的某些操作 你增加了一层间接性,摆脱了语言的常规。对该语言有经验的人会更快地掌握cout,否则他们将不得不寻找宏的内容并习惯它。 肯定有其他理由支持或反对这样的选择,但最终我认为没有正确的选择

附言


与宏观概念混淆,因为通常情况下,更好是一个非常模糊的术语,它实际上取决于你想要实现什么

每个实施决策都有其优缺点,因此它实际上取决于单个项目

据我所见,在宏后面抽象输出的好处可能是:

交换输出方法的更简单方法,有利于在需要时使用更易于管理的日志结构 少打字 如果宏负责添加一些常用格式选项,则会更加统一 缺点可能是:

您将失去灵活性,因为宏将不可避免地不允许直接使用cout所允许的某些操作 你增加了一层间接性,摆脱了语言的常规。对该语言有经验的人会更快地掌握cout,否则他们将不得不寻找宏的内容并习惯它。 肯定有其他理由支持或反对这样的选择,但最终我认为没有正确的选择

附言


与宏混淆,因为这是第三个测试+在一个测试中包含两个字符串;Re:正常情况下,最大的区别是cout@dudewho想学习它基本上是关于在圆形轮子工作时不重新发明方形轮子well@idclev463035818:这种情况在C++20中通过:-输出得到解决。这是第三个测试+,其中包含两个字符串;Re:正常情况下,最大的区别是cout@dudewho想学习它基本上是关于在圆形轮子工作时不重新发明方形轮子well@idclev463035818:这种情况在C++20中通过:-解决,所有这些都可以通过函数而不是宏更干净地完成。@walnut 1它取决于更干净的定义。2然后将所有输出与

即使与给定输出级别不相关的函数也将被编译并包含在二进制文件中。如果您制作函数模板,则只会编译用例。@核桃所有函数调用都将被编译并包含在内。即使对于给定的输出电平也不需要。或者有解决这个问题的方法吗?将函数作为模板,让每个日志级别都有一个唯一的类型,然后,将目标日志级别设置为编译时常量,并进行检查,如果该级别与if constexpr或部分专门化不匹配,则只需将函数体设置为空,尽管这并不重要,因为如果目标日志级别是编译时常量,编译器无论如何都会优化调用。所有这些都可以通过函数而不是宏更干净地完成。@walnut 1这取决于更干净的定义。2然后,所有包含与给定输出级别无关的函数的输出都将被编译并包含到二进制文件中。如果您制作函数模板,则只会编译用例。@walnut所有函数调用都将被编译并包含。即使对于给定的输出电平也不需要。或者有解决这个问题的方法吗?将函数作为模板,让每个日志级别都有一个唯一的类型,然后,将目标日志级别设置为编译时常量,并进行检查,如果该级别与if constexpr或部分专门化不匹配,则只需将函数体设置为空,尽管这并不重要,因为如果目标日志级别是编译时常量,编译器无论如何都会优化调用。为什么不使用函数模板而不是宏?@walnut这个问题专门问宏,所以我解决了这个问题。模板函数仍然会给你几乎相同的优点和缺点,至少是我在答案中写的那些。现在的问题是,你应该做这样的事情吗?。不应该这样做的原因是,在几乎所有情况下,使用函数都是一个更好的选择。@FrançoisAndrieux几乎:@bracco23几乎是在你需要uu文件或类似的情况下进行对冲。但是答案不应该针对边缘情况,除非它们是问题的主题。为什么不使用函数模板而不是宏?@walnut这个问题专门针对宏,所以我解决了这个问题。模板函数仍然会给你几乎相同的优点和缺点,至少是我在答案中写的那些。现在的问题是,你应该做这样的事情吗?。不应该这样做的原因是,在几乎所有情况下,使用函数都是一个更好的选择。@FrançoisAndrieux几乎:@bracco23几乎是在你需要uu文件或类似的情况下进行对冲。但答案不应该针对边缘案例,除非它们是问题的主题。