[英]How do I define an explicit specialization of a template member function in .cpp file
[英]How do I define a macro to print file, function, line in cpp?
我正在尝试打印 function,它在打印语句前面加上文件、function 和行号。
function debug("test %d", 1)
应该打印:
[src/main.cpp:main():8] test 1
这个答案声称可以做我想做的事,并且几乎可以做到,但不能按原样工作。 (而且这个问题与这个问题不一样)使用那个答案,我能够想出这个宏:
#include <cstdio> //needed for printf
#define debug(a, args...) printf("[%s:%s():%d] " #a "\n", __FILE__, __func__ , __LINE__, ##args)
这与我想要的非常接近,但在字符串周围添加了引号,如下所示。 没有引号如何打印?
[src/main.cpp:main():8] "test 1"
您的宏定义有两个问题:
a
; 在这种情况下,您不能简单地将变量放在 2 个字符串文字旁边进行连接。 后一个问题可以通过使用字符串和+
运算符或简单地使用多个printf
来解决。
如果 C++20 __VA_OPT__
可用,则可以使用以下解决方案。
#include <cstdio>
#include <utility>
namespace Logging
{
template<typename ...Args>
inline void Debug(size_t lineNumber, char const* filename, char const* functionName, char const* format, Args&&... args)
{
std::printf("[%s:%s():%zu] ", filename, functionName, lineNumber);
std::printf(format, std::forward<Args>(args)...);
std::printf("\n");
}
}
#define debug(format, ...) ::Logging::Debug(__LINE__, __FILE__, __func__, format __VA_OPT__(,) __VA_ARGS__)
Pre C++ 20 你可以创建一个帮助程序 object 来处理仅使用单个参数的宏的情况
#include <cstdio>
#include <utility>
namespace Logging
{
class Logger
{
public:
Logger(size_t lineNumber, char const* filename, char const* functionName, char const* format)
: m_lineNumber(lineNumber), m_filename(filename), m_functionName(functionName), m_format(format)
{}
template<class ...Args>
inline void Debug(Args&&... args)
{
std::printf("[%s:%s():%zu] ", m_filename, m_functionName, m_lineNumber);
std::printf(m_format, std::forward<Args>(args)...);
std::printf("\n");
}
private:
size_t m_lineNumber;
char const* m_filename;
char const* m_functionName;
char const* m_format;
};
}
#define debug(format, ...) ::Logging::Logger(__LINE__, __FILE__, __func__, format).Debug(__VA_ARGS__)
仅将#a
替换为a
:
#define debug(a, args...) printf("[%s:%s():%d] " a "\n", __FILE__, __func__, __LINE__, ##args)
单个#
后跟宏参数将参数字符串化。 IOW,它接受调用者传递给参数的任何内容,并从中生成字符串文字。 例如:
#define macro(a) #a
macro(1)
将是"1"
, macro(x+y)
将是"x+y"
,等等。
如果参数包含引号字符,它们将作为实际字符存储在字符串文字中,这不是您在这种情况下想要的。 您的参数正在传递一个您想按原样使用的字符串文字,因此简单的宏替换就足够了,因此您需要删除#
。 您希望编译器看到"[%s:%s():%d] " "test %d" "\n"
并因此将它们合并到"[%s:%s():%d] test %d\n"
,看不到"[%s:%s():%d] " "\"test %d\"" "\n"
并将它们合并到"[%s:%s():%d] \"test %d\"\n"
,这是您在原始代码中看到的情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.