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

Blu*_*bie 11 c++ c-preprocessor c++11

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

概念示例:

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

输出:

exampleoutputfillertext
Run Code Online (Sandbox Code Playgroud)

Mik*_*han 20

您不需要预处理器宏来执行此操作.你可以用普通的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');
}
Run Code Online (Sandbox Code Playgroud)

现场演示

在C++ 17中:

template<typename ...Args>
void log(Args && ...args)
{
    (std::cout << ... << args);
}
Run Code Online (Sandbox Code Playgroud)

只需要一切.现场演示

输出:

Hellobravenewworld!
1234
Run Code Online (Sandbox Code Playgroud)

研究可变参数模板, 参数包折叠表达式 而不是可变参数宏,它们在现代C++中很少使用.


Cyg*_*sX1 12

使用可变参数宏时,需要__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;
}
Run Code Online (Sandbox Code Playgroud)

现在,LOG调用将扩展为:

std::cout , "example" , "output" , "filler" , "text" , std::endl;
Run Code Online (Sandbox Code Playgroud)

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

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

  • 据我所知,首先支持可变参数宏的每个C/C++编译器都支持`__VA_ARGS__`.变量宏是C和C++ 11中的标准,但不是C++. (4认同)