vico
vico

Reputation: 18201

Passing <<value to macro

I would like to make macro which could handle stream passed to it. How to handle "hello" in macro body passed passed by "<<"

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

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

    return 0;
}

Upvotes: 2

Views: 1186

Answers (4)

ex-bart
ex-bart

Reputation: 1392

You seem to confuse macros and functions. Macros are something completely different from functions; they do textual replacement in a preprocessor, before the actual compiler even sees to code. Let me fix your example slightly (I'll explain below):

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

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

    return 0;
}

The preprocessor then genrates something like this:

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

    return 0;
}

Which is obviously bogus.

What you probably meant was either

  1. Some prefix which is contained in some static variable value which should be output each time you use MY_MACRO. Then you want

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

    Note1: The space after MY_MACRO is important.

    Note2: It will often work without the parens around (std::cout<<value), but you should include them to be on the safe side. That will most likely save you some headache later.

  2. You want to give an argument to MY_MACRO, and it should be possible to specify complex constructs there (e.g. MY_MACRO("The answer is " << 42)). Then you want to use something like

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

    Note3: Often it is advised to put parans around the macro parameters, and usually that is a good idea. Not in this case however, because then MY_MACRO("The answer is " << 42); would expand to (std::cout << ("The answer is " << 42));, which would try to shift a character pointer left by 42 bits before piping it into std::cout.

Now to get back to the first little fix I mentioned. Originally you defined a function-style macro #define MY_MACRO().... This will only be replaced by the preprocessor if it appears in the program text followed by an opening paren (, like so: MY_MACRO()<<"hello";. I removed the emtpy pair of parens in the macro definition, making it an object-style macro. If you try to define an object-style macro with a replacement text that starts with an opening paren (, you have to seperate the macro name and the paren by whitespace to disambiguate it from a function-style macro definition. That's what Note1 was about.

Upvotes: 1

NathanOliver
NathanOliver

Reputation: 180945

A macro does a text substitution. If we expand it your source becomes:

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

Which is not going to work.

Now you can rewrite your macro to:

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

And you would use it like:

#include <iostream>
#include <string>

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

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

Live Example

Upvotes: 1

Mark Jansen
Mark Jansen

Reputation: 1509

Take a look at glog (Google log), it allows logging like:

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

https://github.com/google/glog

Upvotes: 0

ForEveR
ForEveR

Reputation: 55897

There is no way to do such thing. You can do this only with operator overloading. Of course you can do

#define MY_MACRO std::cout

but it's not what you want.

Upvotes: 0

Related Questions