C ++ Macros and Templates

Is there any way to get through

std::map<std::string, float> 

How is the macro argument?

(the problem is that "," is used by the macro to separate

 std::map<std::string 

and

 float> 

as separate arguments. I would like to avoid this.

+4
source share
6 answers

No, there is no way to do this unless you use a typedef. BOOST_FOREACH, for example, is experiencing the same problem.

+6
source

Try using a template instead of a macro.

Scott Meyers: Effective C ++ Point 2: Prefer constants, enumerations and strings in #defines

+6
source

Yes, there is a way, it is indirect, though.

As you said, a macro is pretty dumb in its interpretation. However, it still recognizes the parentheses.

Example: BOOST_MPL_ASSERT((boost::is_same<int,int>))

It works using a different level of parentheses, thus forming a Tuple (from a macro point of view).

If you use the Boost.Preprocessor library, you can easily "deploy" Tuple to get its contents intact. Unfortunately, you must know the size of the tuple, so you need an additional parameter

 #define MY_MACRO(Size, TemplatedType, Name)\ BOOST_PP_TUPLE_REM(Size)(TemplatedType) Name 

And in action:

 MY_MACRO(2, (std::map<int,std::string>), idToName); // expands to 'std::map<int,std::string> idToName' idToName[1] = "Smith"; 

So yes, it is possible, but the macro must be explicitly configured to handle it.

+5
source

One ineffective workaround is to β€œhide” the comma inside another macro

 #define ARGUMENT std::map<std::string, float> YOUR_MACRO(ARGUMENT) #undef ARGUMENT 

However, if YOUR_MACRO must itself distribute it to another level in another macro, it will face the same problem.

+2
source

I had something similar a few months ago, if you use a macro and have parameters containing a comma (','), you need to enclose them in an additional parenthesis, i.e.:

 #define DEF(ret,conv,name,args) typedef ret (conv * name)(args) //usage DEF(void,__cdecl,Foo,(int a1, string a2)); 

this method may conflict with certain things / be invalid in some cases, like this example (this leads to the fact that it becomes an invalid c-style application):

 #define MY_VAR(type,name) type name //usage MY_VAR((std::map<std::string, float>),Map); 

There is one way to solve this problem, but this requires your compiler to support variable macros ( GCC | MSVC ):

 #define _W(...) __VA_ARGS__ #define VAR(x,y) xy VAR(_W(std::map<std::string, float>),Map); 
0
source

Yes, for so long you can arrange it so that std::map<std::string, float> your final or only parameter. Just use __VA_ARGS__ , for example:

 #define MAKE_A_NEW_ONE_OF_THESE(a, ...) __VA_ARGS__ *a = new __VA_ARGS__ MAKE_A_NEW_ONE_OF_THESE(pMyMap, std::map<std::string, float>); 
0
source

Source: https://habr.com/ru/post/1301797/


All Articles