我最近开始使用C ++而且我已经感受到强烈的冲动
#define print(msg) std::cout << msg << std::endl
这会在所有情况下都能正确执行吗?这是我所知道的唯一一个在msg中有<<
时可以使用的公式(例如"foo" << myInt
)。既不
#define print(msg) std::cout << (msg) << std::endl // note: parens
也不是建议的答案
template<typename T>
void print(T const& msg) {
std::cout << msg << std::endl;
}
在这种情况下工作。我也不关心使用endl
而仅使用\n
来刷新输出的效率。
答案 0 :(得分:5)
既然您提到最近刚开始使用 C ++ ,我想向您展示该语言提供的更好的替代方案:
template<typename T>
void print(T const& msg)
{
std::cout << msg << std::endl;
}
任何类型需要一个msg
参数,并通过std::cout
将其流出。
正如评论中所提到的,std::endl
不仅会插入新行,还会刷新流。这类似于printf
\n
上的std::cout << msg << '\n';
。如果你只想要一个新的产品系列,而且你可能会这样做,那么最好明确地做到这一点:
{{1}}
答案 1 :(得分:3)
这是非常主观的,但是您只需编写一次代码并多次阅读。代码的其他维护者想要了解你所编写的内容,所以只要写出std::cout << msg << std::endl
就是你的意思了。不要试图让C ++看起来像另一种语言。
答案 2 :(得分:2)
只是为了好玩,这里有两个print
的可变C ++ 11实现:一个在参数之间插入空格,另一个不插入空格。 (住在ideone。)
#include <iostream>
namespace with_spaces {
namespace detail {
std::ostream& print(std::ostream& os) {
return os;
}
template <typename T>
std::ostream& print(std::ostream& os, T&& t) {
return os << std::forward<T>(t);
}
template <typename T, typename U, typename... Args>
std::ostream& print(std::ostream& os, T&& t, U&& u, Args&&... args) {
return print(print(os, std::forward<T>(t)) << ' ', std::forward<U>(u), std::forward<Args>(args)...);
}
}
template <typename... Args>
void print(Args&&... args) {
detail::print(std::cout, std::forward<Args>(args)...) << std::endl;
}
}
namespace without {
namespace detail {
std::ostream& print(std::ostream& os) {
return os;
}
template <typename T>
std::ostream& print(std::ostream& os, T&& t) {
return os << std::forward<T>(t);
}
template <typename T, typename... Args>
std::ostream& print(std::ostream& os, T&& t, Args&&... args) {
return print(print(os, std::forward<T>(t)), std::forward<Args>(args)...);
}
}
template <typename... Args>
void print(Args&&... args) {
detail::print(std::cout, std::forward<Args>(args)...) << std::endl;
}
}
#include <iomanip>
int main() {
std::cout << std::boolalpha;
with_spaces::print(1, "foo", new int(3), 0xFFFFFFFFFFULL, 42, 0 == 1);
without::print(1, "foo", new int(3), 0xFFFFFFFFFFULL, 42, 0 == 1);
}
我觉得有多少代码可以完成简单的单行宏可以做的事情。
答案 3 :(得分:0)
宏被广泛使用,但不是很好的做法(特别是在C ++中),因为它们可以隐藏真正发生的事情,并且无法调试代码。
宏也绕过了预处理器的类型检查,可能导致运行时问题。
如果您正在尝试优化速度,我建议使用内联函数。