如何为std :: cout创建一个可变宏?

时间:2015-03-29 06:52:19

标签: c++ c++11 c-preprocessor

我如何创建一个带有可变数量参数的宏,并使用std :: cout打印出来?很抱歉,如果这是一个noob问题,在搜索答案后找不到任何澄清可变参数的宏。

概念示例:

#include <iostream>
#define LOG(...) std::cout << ... << ... << std::endl
int main() {
    LOG("example","output","filler","text");
    return 0;
}

会输出:

exampleoutputfillertext

4 个答案:

答案 0 :(得分:17)

您不需要预处理器宏来执行此操作。你可以用普通的方式写 C ++。在C ++ 11/14中:

#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!\n");
    log("1", 2,std::string("3"),4.0,'\n');
}

Live demo

在C ++ 17中:

template<typename ...Args>
void log(Args && ...args)
{
    (std::cout << ... << args);
}

只需要。 Live demo

输出:

Hellobravenewworld!
1234

研究variadic templatesparameter packsfold expressions 而不是可变宏,这在现代C ++中很少有用。

答案 1 :(得分:10)

使用可变参数宏时,需要__VA_ARGS__来扩展所有参数。 但问题是这些参数是逗号分隔的。据推测,它只是将参数分离为函数调用,但由于宏只与文本一起使用,因此实际上也可以在其他上下文中使用__VA_ARGS__,其中逗号分隔列表是有意义的。

您可以使用的技巧是为std::ostreamstd::cout的类型)定义您自己的逗号运算符。例如:

#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调用将扩展为:

std::cout , "example" , "output" , "filler" , "text" , std::endl;

并且逗号将调用重载的逗号运算符。

如果您不喜欢重载operator,污染所有std::ostream - s,则可以使用您自己的特殊记录器类封装std::cout

答案 2 :(得分:1)

不确定在C ++中是否有任何定义可变参数宏的方法(至少不是可移植的方式)。为什么不使用可变参数模板方法?像

这样的东西
#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");
}

答案 3 :(得分:0)

您可以尝试这个

#include <iostream>

#define LOG() std::cout

int main()
{
    LOG() << "Hello! " << "how " << "are " << "you " << std::endl;
    return 0;
}

输出:

Hello!  how are  you