Is it possible to prefix each element of variadic parameters with something else?
#define INPUTS(...) ???
Function(INPUTS(a, b, c))
should become
Function(IN a, IN b, IN c)
Take a look at Boost.Preprocessor.
While daunting, it can be used to do all kinds of weird things, like exactly this:
#include <boost/preprocessor.hpp>
#define MAKE_IN_ARG(r,_,arg) (IN arg)
#define ARGS(...) \
BOOST_PP_SEQ_TO_TUPLE( \
BOOST_PP_SEQ_FOR_EACH(MAKE_IN_ARG,, \
BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)))
void f ARGS( int a, float b, char c )
{
//...
}
Produces:
void f (IN int a, IN float b, IN char c )
{
}
That said...
You are making a mistake. Don’t do this. Just type out the IN in front of every input argument when you write the function header. Your life will be significantly easier.
Related
In the class there are a lot of methods with similar implementation, only method's name and argument-list different:
void function1 (int a, bool b)
{
mMember->function1(a, b);
}
void function2 (double a, string b)
{
mMember->function2(a, b);
}
It is required to replace all them with variadic macro.
Something like this
#define MYMACRO(funcname, ...) void funcname (__VA_ARGS__) { mMember->funcname (__VA_ARGS__)}
but it is generated into such call
mMember->function1(int a, bool b)
And of course gives compilation errors.
How can parameters' values be got inside macro, so that to pass them into mMember->funcname without types?
mMember->function1(a, b)
How can parameters' values be got inside macro, so that to pass them into mMember->funcname without types?
It is not possible. The typical solution is to pass types and variables in separate arguments and have two separate chains of expansions. This will not work without typedef for function types or array types.
// Macro overloading on number of arguments left for the reader.
// This is a static example for 4 arguments.
#define MYMACRO_ARGS(a, b, c, d) a b, c d
#define MYMACRO_PARAM(a, b, c, d) b, d
#define MYMACRO(funcname, ...) \
void funcname(MYMACRO_ARGS(__VA_ARGS__)) { \
mMember->funcname(MYMACRO_PARAM(__VA_ARGS__)); \
}
MYMACRO(function2, double, a, string, b)
Overall, I recommend not doing it. Hiding your code behind a macro will make your code harder to read and maintain. Strongly consider just writing the stuff out, instead of making it very hard for linters, code analyzers, and programmers and confusing yourself with unreadable error messages from the compiler.
To reduce the number of lines to be written, i am using macros in the following way:
#define FUNC(a, b) func(a, b, threadId, sizeof(a)); \
do something 1; \
do something 2;
This works well, as i just need to use the macro (with 2 parameters) that encodes the function call (with 4 parameters) and 2 or more other statements.
Problem arises when this function call is a parameter to another function.
For example, suppose i need the following code:
func1(par1, func(a, b, c, d));
do something 1;
do something 2;
Is there a way to achieve this using macros, or any other alternatives?
i.e. I am expecting something like:
func1(par1, FUNC(a, b)); //This statement(using macros) should transform into the above code after the preprocessing step.
I'm not sure what you are actually trying to achieve, but replacing this:
#define FUNC(a, b) func(a, b, threadId, sizeof(a)); \
do something 1; \
do something 2;
by this (assuming the type of the a and b parameters is int):
int FUNC(int a, int b)
{
int returnvalue = func(a,b,threadId, sizeof(a));
do something 1;
do something 2;
return returnvalue;
}
should do the job.
You could try to isolate the code with brackets { }. But your idea is not one I would recommend, as the code becomes very hard to understand and debug.
#define FUNC(a, b) { func(a, b, threadId, sizeof(a)); \
do something 1; \
do something 2; }
But if you try to send this as a parameter to another function it still won't work because you are not returning anything to be uses as a parameter ( no adress, no value)
Given that I'd prefer to keep numbers in my program as ints or whatever integral, what is the most convenient way of doing an arbitrary arithmetic with floating point equivalents of those numbers?
Say, I have
int a,b,c,d;
double x;
And I want to write
x=a/b/c/d+c/d+a;
without turning the expression into mess by putting conversions everywhere in parsed operator tree leafs like
x=(double)a/b/c/d+(double)c/d+a;
Is it doable with C-style macro (recursive or not)? Should it be done with new class and overloaded operators?
x=a/b/c/d+c/d+a;
This is a pretty complex expression. Better give it a name:
double complex_expression(double a, double b, double c, double d) {
return a/b/c/d+c/d+a;
}
Now when you call that with integer arguments, since the parameters are of type double the arguments get converted to double using the usual arithmetic conversions:
int a,b,c,d;
// Init them somehow
double x = complex_expression(a,b,c,d);
With a C++11 lambda ...
int a,b,c,d;
// Init them somehow
double x = [](double a, double b, double c, double d) {
return a/b/c/d+c/d+a; }(a,b,c,d);
... works, but IMO somehow looks clumsy.
Slightly better?
double x = [a = (double)a, b = (double)b, c = (double)c, d = (double) d] {
return a/b/c/d+c/d+a; }();
Oh, and if you're in for some macro fun:
#define SPLICE_2(l,r) l##r
#define SPLICE_1(l,r) SPLICE_2(l,r)
#define SPLICE(l,r) SPLICE_1(l,r)
#define TREAT_AS(type, name) name = static_cast<type>(name)
#define TREAT_ALL_AS_HELPER_0(type)
#define TREAT_ALL_AS_HELPER_1(type, name) TREAT_AS(type, name)
#define TREAT_ALL_AS_HELPER_2(type, name, ...) TREAT_AS(type, name), TREAT_ALL_AS_HELPER_1(type, __VA_ARGS__)
#define TREAT_ALL_AS_HELPER_3(type, name, ...) TREAT_AS(type, name), TREAT_ALL_AS_HELPER_2(type, __VA_ARGS__)
#define TREAT_ALL_AS_HELPER_4(type, name, ...) TREAT_AS(type, name), TREAT_ALL_AS_HELPER_3(type, __VA_ARGS__)
#define TREAT_ALL_AS_HELPER_5(type, name, ...) TREAT_AS(type, name), TREAT_ALL_AS_HELPER_4(type, __VA_ARGS__)
// expand as you will
#define TREAT_ALL_AS(type, count, ...) SPLICE(TREAT_ALL_AS_HELPER_, count)(type, __VA_ARGS__)
Now use as
double x = [TREAT_ALL_AS(double, 4, a, b, c, d)] {
return a/b/c/d+c/d+a; }();
You can also automatically count the number of variadic macro arguments.
But to be honest, IMO its best to just write a named function.
I am using the X macro pattern to keep a bunch of arrays/items in sync, and I want to create an argument list from it, however I can't work out a way to get a well formed list. Here's what I mean:
#define MY_DATA \
X(var_one, e_one, 1) \
X(var_two, e_two, 2) \
X(var_three, e_three, 3) \
#define X(a,b,c) b,
enum MyNumbers {
MY_DATA
};
#undef X
#define X(a,b,c) c,
int MyValues[] = {
MY_DATA
};
#undef X
void my_func(int a, int b, int c) {} // example do-nothing proc
void main(void)
{
int var_one = MyValues[e_one];
int var_two = MyValues[e_two];
int var_three = MyValues[e_three];
#define X(a,b,c) a,
my_func(MY_DATA); // this fails because of the trailing comma
#undef X
}
Macros are not really my forte, so I can't think of a way of getting rid of the final comma in the function call. Can anyone think of a way to stop it?
Look at the Boost Preprocessor library for “preprocessor metaprogramming tools including repetition and recursion.”
Even if you don't use their complete package, the chapter I linked to explains some techniques, specifically including iteration to build data structures and statements.
Here's an idea: write
my_func(MY_DATA 0);
and declare my_func to take an extra (ignored) argument.
void my_func(int a, int b, int c, int)
I use a variant of this pattern frequently. However, it is normally used to define mappings between data. Along the lines of this:
MESSAGE(10, "Some error message"),
MESSAGE(11, "Som other error message"),
What des not make sense in your approach is that typically these constructs are used for large numbers of entries (100s, 1000s). You normally do not want that many arguments to a function.
If you really want to follow the approach, you could add another MACRO
#define MY_DATA \
X(var_one, e_one, 1) COMMA \
X(var_two, e_two, 2) COMMA \
X(var_three, e_three, 3) \
and define comma as needed when you define X. (Or you could just put the comma in directly).
Here is an option:
void my_func(int a, int b, int c, int dummy) {}
// ...
my_func(MY_DATA 0);
If you can't change my_func then make a thunk (i.e. an intermediate function that calls my_func)
A second option would be to include the comma in the MY_DATA macro instead of in X:
#define MY_DATA \
X(var_one, e_one, 1), \
X(var_two, e_two, 2), \
X(var_three, e_three, 3)
#define DEFINE_STAT(Stat) \
struct FThreadSafeStaticStat<FStat_##Stat> StatPtr_##Stat;
The above line is take from Unreal 4, and I know I could ask it over on the unreal forums, but I think this is a general C++ question that warrants being asked here.
I understand the first line defines a macro, however I am not well versed in preprocessor shenanigans in C++ and so I'm lost over there. Logic tells me the backslash means the declaration continues onto the next line.
FThreadSafeStaticStat looks a bit like a template, but there's #'s going on in there and a syntax I've never seen before in C++
Could someone tell me what this means? I understand that you may not have access to Unreal 4, but it's just the syntax I don't understand.
## is the preprocessor operator for concatenation.
So if you use
DEFINE_STAT(foo)
anywhere in the code, it gets replaced with
struct FThreadSafeStaticStat<FStat_foo> StatPtr_foo;
before your code is compiled.
Here is another example from a blog post of mine to explain this further.
#include <stdio.h>
#define decode(s,t,u,m,p,e,d) m ## s ## u ## t
#define begin decode(a,n,i,m,a,t,e)
int begin()
{
printf("Stumped?\n");
}
This program would compile and execute successfully, and produce the following output:
Stumped?
When the preprocessor is invoked on this code,
begin is replaced with decode(a,n,i,m,a,t,e)
decode(a,n,i,m,a,t,e) is replaced with m ## a ## i ## n
m ## a ## i ## n is replaced with main
Thus effectively, begin() is replaced with main().
TLDR; ## is for concatenation and # is for stringification (from cppreference).
The ## concatenates successive identifiers and it is useful when you want to pass a function as a parameter. Here is an example where foo accepts a function argument as its 1st argument and the operators a and b as the 2nd and 3rd arguments:
#include <stdio.h>
enum {my_sum=1, my_minus=2};
#define foo(which, a, b) which##x(a, b)
#define my_sumx(a, b) (a+b)
#define my_minusx(a, b) (a-b)
int main(int argc, char **argv) {
int a = 2;
int b = 3;
printf("%d+%d=%d\n", a, b, foo(my_sum, a, b)); // 2+3=5
printf("%d-%d=%d\n", a, b, foo(my_minus, a, b)); // 2-3=-1
return 0;
}
The # concatenates the parameter and encloses the output in quotes. The example is:
#include <stdio.h>
#define bar(...) puts(#__VA_ARGS__)
int main(int argc, char **argv) {
bar(1, "x", int); // 1, "x", int
return 0;
}