How to make a variadic macro for std::cout?
我如何制作一个带有可变数量参数的宏,并使用std :: cout打印出来? 很抱歉,如果这是一个菜鸟问题,在寻找答案后找不到任何能够阐明可变参数宏的内容。
概念示例:
1 2 3 4 5 6 | #include <iostream> #define LOG(...) std::cout << ... << ... << std::endl int main() { LOG("example","output","filler","text"); return 0; } |
将输出:
1 | exampleoutputfillertext |
您不需要预处理器宏即可执行此操作。你可以用普通的方式写
C ++。在C ++ 11/14中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <iostream> #include <utility> void log(){} template<typename First, typename ...Rest> void log(First && first, Rest && ...rest) { std::cout << std::forward<First>(first); log(std::forward<Rest>(rest)...); } int main() { log("Hello","brave","new","world! "); log("1", 2,std::string("3"),4.0,' '); } |
现场演示
在C ++ 17中:
1 2 3 4 5 | template<typename ...Args> void log(Args && ...args) { (std::cout << ... << args); } |
就是全部。现场演示
输出:
1 2 | Hellobravenewworld! 1234 |
研究可变参数模板,
参数包
和折叠表达式
而不是可变参数宏,在现代C ++中很少使用。
使用可变参数宏时,您需要
但是,问题在于这些参数是用逗号分隔的。大概是,它只是将参数分开给函数调用,但是由于宏仅与文本一起使用,因此您实际上还可以在其他上下文中使用
您可以采用的技巧是为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include<iostream> #define LOG(...) std::cout , __VA_ARGS__ , std::endl template <typename T> std::ostream& operator,(std::ostream& out, const T& t) { out << t; return out; } //overloaded version to handle all those special std::endl and others... std::ostream& operator,(std::ostream& out, std::ostream&(*f)(std::ostream&)) { out << f; return out; } int main() { LOG("example","output","filler","text"); return 0; } |
现在,LOG调用将扩展为:
1 | std::cout ,"example" ,"output" ,"filler" ,"text" , std::endl; |
逗号将调用重载的逗号运算符。
如果您不喜欢过载的
不确定是否有任何方法可以在C ++中定义可变参数宏(至少不是可移植的方法)。为什么不使用可变参数模板方法?就像是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include <iostream> void LOG() {} template<typename Head, typename... Args> void LOG(const Head& head, const Args&... args ) { std::cout << head <<""; LOG(args...); } int main() { LOG("This","is" ,"the", 3,"rd test"); } |
你可以试试这个
1 2 3 4 5 6 7 8 9 | #include <iostream> #define LOG() std::cout int main() { LOG() <<"Hello!" <<"how" <<"are" <<"you" << std::endl; return 0; } |
输出:
1 | Hello! how are you |