Your two alternatives are identical. The order that macros are defined in is irrelevant to their expansion; it's only relevant what they are defined as at the time of expansion.
Why is this happening ?
You're invoking the macro repf
with two arguments, but it takes three arguments. That is an error, plain and simple, so preprocessing fails.
What could have been implementation problem for C++ Pre-Processor implementors, that they avoided this feature ?
I think you're making an unwarranted assumption here. The issue isn't that the preprocessor "lacks" some "feature"; it's that your expectations of how the preprocessor works is wrong.
Presumably, you expect the preprocessor to do something like this:
repf(arr, stlf(arr))
repf(arr, arr.begin(), arr.end())
for(auto it = arr.begin() ; it != arr.end() ; ++it)
...where from step 1 to step 2, stlf(arr)
gets expanded; then its expansion is put into the call to repf
, which then gets expanded at step 3.
The problem is, that is not how the preprocessor works. Given the example is broken, I can't illustrate the steps properly with this, so let's suppose we do this instead for illustration purposes:
#define FOO(X, Y) BAR(X, Y)
#define BAR(X,Y,Z) x is X y is Y z is Z
#define ACOMMAB A, B
FOO(ACOMMAB, C)
That last line expands to x is A y is B c is Z
, and it works more like this:
FOO(ACOMMAB, C)
BAR(ACOMMAB, C)
BAR(A, B, C)
x is A y is B c is Z
Note that the inner macro doesn't expand first; rather, the outer macro does. Note also that this example injects a comma; so injecting a comma is definitely something you can in fact do, which I assume to be the "feature" you refer to that was avoided.
How can I then use such shortcuts ??
Given the preprocessor doesn't work the way you think it does, you probably don't want to use it to do what you think you want to use it to do... even for speed coding. stlf
will gladly build two arguments for you for function calls, but macros are not functions. Ranged for seems to be your best bet.