无论如何,是否可以将以下内容写为 C++宏?
my_macro << 1 << "hello world" << blah->getValue() << std::endl;
应该扩展到:
std::ostringstream oss;
oss << 1 << "hello world" << blah->getValue() << std::endl;
ThreadSafeLogging(oss.str());
my_macro << 1 << "hello world" << blah->getValue() << std::endl;
should expand into:
std::ostringstream oss;
oss << 1 << "hello world" << blah->getValue() << std::endl;
ThreadSafeLogging(oss.str());
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
创建一个
my_stream
类型的临时文件,它是ostringstream
的子类。对该临时对象的所有操作都像在ostringstream
上一样工作。当语句结束时(即在 main() 中整个打印操作的分号之后),临时对象超出范围并被销毁。
my_stream
析构函数使用之前“收集”的数据调用ThreadSafeLogging
。已测试(g++)。
感谢/感谢 dingo 指出如何简化整个事情,所以我不知道不需要重载的
运算符<<
。可惜投票不能分享。A temporary of type
my_stream
is created, which is a subclass ofostringstream
. All operations to that temporary work as they would on anostringstream
.When the statement ends (ie. right after the semicolon on the whole printing operation in main()), the temporary object goes out of scope and is destroyed. The
my_stream
destructor callsThreadSafeLogging
with the data "collected" previously.Tested (g++).
Thanks/credits to dingo for pointing out how to simplify the whole thing, so I don't need the overloaded
operator<<
. Too bad upvotes can't be shared.难道你不能从 ostream 派生并提供你自己的线程安全实现吗?那么您可以
在没有宏的情况下正确使用 C++ 并获得完全相同的功能吗?
Couldn't you just derive from ostream and provide your own thread safe implementation? Then you could just do
And get the exact same functionality without macros and using C++ properly?
问题是,如果不使用函数语法,宏就只能在其所在位置进行替换。
但是如果您愿意使用函数语法,则可以替换参数之前和之后的内容。
您可以将 MyMacro 定义为:
No. The problem is that without using function syntax, a macro is limited to only being replaced where it is.
But if you were willing to use function syntax, you can then replace stuff both before and after the args.
You could by defining MyMacro as:
看看 google-glog,他们使用一个用 a 实例化的临时对象来做到这一点
,他们也有其他有趣的宏,例如 LOG_IF 等。
Take a look at google-glog, they do this using a temporary object instanciated with a
and they also have other interesting macros such as LOG_IF et al.
考虑到您的代码中包含了这些行,是的,
所有标准编译器都可能定义了 __LINE__ 宏。
因此,我们可以使用它来生成一个变量名,每次使用宏时该变量名都不同:)
这是一个新版本,仅被视为单语句指令:
(已编辑)
由于运算符
<<
的简单性,开发人员可能不需要在同一行上使用该宏两次。但如果您需要这个,您可以将__LINE__
的使用切换为__COUNTER__
(这是非标准的!)。感谢 Quuxplusone 提供的建议Considering you have these lines included somewhere in your code, yes it is possible
__LINE__
macro is defined by all standart compilers.So we can use it to generate a variable name wich is different each time you use the macro :)
Here is a new version that is seen as a one-statement instruction only:
(EDITED)
Developper probably won't need to use this macro twice on same line becasue of simplicity of operator
<<
. But in case you need this, you can switch the use of__LINE__
by__COUNTER__
(which is non standard!). Thanks to Quuxplusone for this tip这是我在其他地方看到的另一个令人讨厌的把戏。与我的其他答案相比,它有一个显着的缺点:您不能在同一范围内使用它两次,因为它声明了一个变量。但是,对于其他情况(您希望
somemacro foo
在foo之后运行某些内容)可能仍然很有趣。Here's another nasty trick I saw somewhere else. It has a significant disadvantage compared to my other answer: you can't use it twice in the same scope because it declares a variable. However, it may still be interesting for other cases where you want to have
somemacro foo
run something afterfoo
.我的日志记录设置非常相似:
如果您的日志记录被禁用,则永远不会创建 ostream,并且存在很少的开销。您可以配置日志记录文件名和名称。行号或优先级。 ShouldLog 函数可以在调用之间更改,因此您可以限制或限制输出。日志输出使用两个函数来修改自身,Prefix 向行添加“file:line: (PRIO)”前缀,Flush() 既将其作为单个命令刷新到日志输出,并向其添加换行符。在我的实现中,它总是如此,但如果还不存在,您可以将其作为条件。
The logging setup I have is quite similar:
If your logging is disabled, the ostream is never created and little overhead exists. You can configure logging on file name & line number(s) or priority levels. The ShouldLog function can change between invocations, so you could throttle or limit output. The log output uses two functions to modify itself, Prefix that adds a "file:line: (PRIO) " prefix to the line, and Flush() which both flushes it to the log output as a single command and adds a newline to it. In my implementation it always does, but you can make that conditional if one is not already there.