簡體   English   中英

如何為 std::cout 制作可變參數宏?

[英]How to make a variadic macro for std::cout?

我如何制作一個帶有可變數量參數的宏,並使用 std::cout 打印出來? 對不起,如果這是一個菜鳥問題,在搜索答案后找不到任何澄清可變參數宏的內容。

概念示例:

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

會輸出:

exampleoutputfillertext

您不需要預處理器宏來執行此操作。 你可以用普通的 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');
}

現場演示

在 C++17 中:

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

這就是全部。 現場演示

輸出:

Hellobravenewworld!
1234

研究可變參數模板參數包折疊表達式,而不是可變參數宏,這在現代 C++ 中很少有用。

使用可變參數宏時,您需要__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

不確定是否有任何方法可以在 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");
}

你可以試試這個

#include <iostream>

#define LOG() std::cout

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

輸出:

Hello!  how are  you 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM