[英]How to use Macros in c++?
最近我在 c++17 中遇到了 inline 以及它如何被用作#define
的替代品,但两者都有其缺点。 但是我的问题是,如果我想抽筋整个std::cout << x << '\n';
在一个名为LOG(x)
的简单行中。
答:我应该使用什么,为什么?
B:各有什么优缺点,什么时候用什么?
1.)
#define LOG(x) std::cout << x << '\n'
2.)
void inline LOG(auto x)
{
std::cout << x << '\n';
}
3.)
void LOG(auto x)
{
std::cout << x << '\n';
}
4.)
这个是有人推荐给我的:
template <typename T>
void log(const T& x)
{
std::cout << x << '\n';
}
如何在 c++ 中使用宏?
谨慎。 当没有更好的选择时。
避免这种情况。 宏名称不遵守范围规则,因此更容易受到名称冲突的影响。 另外,考虑一下如果你想记录一个被另一个数字移位的数字会发生什么:
LOG(0x1 << 2);
你会期待什么 output,你会得到什么 output? 他们匹配吗?
亲:它是一个 function(模板),因此不存在与宏相关的问题。 缺点:您按值接受参数。 例如,经常用于日志记录的字符串可能会很昂贵。 需要 C++20。
实际上与 2 相同。 auto
参数将这些转换为隐式内联的 function 模板。
优点:不需要 C++20。 传递了一个引用,这对于传递字符串很有好处。
结论:4.是一个合理的默认选择。
普遍的共识是使用宏不是一个好主意。 但这真正意味着滥用宏不是一个好主意。
解决方案#2 可以,但它的用处相当有限,因为每行只能打印一个值。
inline void LOG(const auto& x)
{
std::cout << x << '\n';
}
// use as:
LOG(x);
这是一个不错的解决方案,但它的使用相当有限。考虑这个用例:
inline void LOG(const auto& x)
{
std::cout << x << '\n';
}
struct point { float x, y; };
// usability is kind of limited, since it will only print one value per line
point p{};
LOG(x);
LOG(y);
// which gives this output.
0
0
// That's not really useful for a log.
宏的一个优点是,您可以使日志 output 更有用一些。
#define LOG(x) std::cout << x << '\n'
struct point { float x, y; };
// usability is better, but still limited,
point p{};
LOG("x: " << p.x << ", y: " << p.y);
// which gives this output.
x: 0, y: 0
这有点好,您正在使用宏,并且您确实可以更好地控制 output,从而使您的日志更有用。 但它对您的代码施加了一些限制......例如,您可能希望在以后使用第三方日志库,或者编写自己的日志库,但是对 LOG() 的某些调用将在其中包含运算符,并且这可能会迫使您重写它们。
因此,除其他外,function 模板会更好,它可以接受任意数量的 arguments。
template <typename... Args>
inline void LOG(Args&&... args)
{
(std::cout << ... << args) << '\n';
}
point p{};
LOG("x: ", p.x, ", y: ", p.y);
// which gives this output.
x: 0, y: 0
如果你想在你的发布版本中失败,我建议使用宏。
#define LOG(...)
// on MSVC
#define LOG(...) __noop
除非您想在 output 中记录变量的符号名称,否则我不会使用 #1(宏版本),例如:
#define LOG(x) std::cout << #x << " = " << x << '\n'
我相信 #2 和 #4 是等价的,因为使用 auto 在引擎盖下引入了模板类型。
#3 略逊一筹,因为它要求您在 header 文件中编写声明,并将定义放在源文件中(因为它不是内联的),这需要更多代码来维护。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.