传递&lt; <value to =“”macro =“”

时间:2015-07-31 13:53:31

标签: c++ visual-c++ metaprogramming

=“”

我想创建可以处理传递给它的流的宏。如何处理“&lt;&lt;&lt;”

传递的宏体中的“hello”
#define MY_MACRO(){std::cout<<value;}

int _tmain(int argc, _TCHAR* argv[])
{
    MY_MACRO<<"hello";

    return 0;
}

4 个答案:

答案 0 :(得分:1)

宏执行文本替换。如果我们扩展它,你的来源就变成了:

{std::cout<<value;}<<"hello";

哪个不起作用。

现在您可以将宏重写为:

#define OUTPUT(x) std::cout << x

你会像以下一样使用它:

#include <iostream>
#include <string>

#define OUTPUT(x) std::cout << x

int main(int argc, char **argv)
{ 
    OUTPUT("test");
}

Live Example

答案 1 :(得分:1)

您似乎混淆了宏和函数。宏与功能完全不同;在实际编译器甚至看到代码之前,它们在预处理器中进行文本替换。让我稍微修改一下你的例子(我将在下面解释):

#define MY_MACRO {std::cout<<value;}

int _tmain(int argc, _TCHAR* argv[])
{
    MY_MACRO<<"hello";

    return 0;
}

预处理器然后产生这样的东西:

int _tmain(int argc, _TCHAR* argv[])
{
    {std::cout<<value;}<<"hello";

    return 0;
}

这显然是假的。

你可能想要的是

  1. 某些前缀包含在某些静态变量value中,每次使用{{1>}时都应输出 。那你想要

    MY_MACRO

    注1: #define MY_MACRO (std::cout<<value) int _tmain(int argc, _TCHAR* argv[]) { MY_MACRO<<"hello"; return 0; } 之后的空格非常重要。

    注意2:它通常会在MY_MACRO周围没有问题的情况下工作,但您应该将它们包含在安全的一边。这很可能会让你后来感到头疼。

  2. 您想为(std::cout<<value)提供参数,并且应该可以在那里指定复杂的构造(例如MY_MACRO)。然后你想使用像

    这样的东西
    MY_MACRO("The answer is " << 42)

    注3:通常建议在宏参数周​​围加上parans,通常这是一个好主意。但是不是在这种情况下,因为#define MY_MACRO(value) (std::cout<<value) int _tmain(int argc, _TCHAR* argv[]) { MY_MACRO("hello"); return 0; } 会扩展为MY_MACRO("The answer is " << 42);,这会尝试将字符指针向左移位42位,然后再将其换成(std::cout << ("The answer is " << 42));

  3. 现在回到我提到的第一个小修复。最初你定义了一个函数式宏std::cout。如果预处理器出现在程序文本中,后面跟一个开头paren #define MY_MACRO()...,则只会被预处理器取代,如下所示:(。我在宏定义中删除了一对emtpy parens,使其成为一个对象样式的宏。如果您尝试使用以开头paren MY_MACRO()<<"hello";开头的替换文本来定义对象样式宏,则必须将宏名称和空格分开,以便从函数式宏定义中消除歧义。这是 Note1 的内容。

答案 2 :(得分:0)

没有办法做这样的事情。您只能在运算符重载时执行此操作。你当然可以做到

#define MY_MACRO std::cout

但它不是你想要的。

答案 3 :(得分:0)

看一下glog(谷歌日志),它允许记录如下:

LOG(INFO) << "Found " << num_cookies << " cookies";

https://github.com/google/glog