2

First, there are a lot of posts on overloading macros:

However, all of them ask the question about variadic macros.

What I'd like to ask is if the following is possible:

#define FOO 3
#define FOO(a,b) a+b

int main() {
  int a = FOO(0,1);
  int b = FOO;
  std::cout << a + b;
  return 0;
}

I'd like for it to work on clang as well.

gust
  • 878
  • 9
  • 23
  • 1
    `#define FOO(a,b) a+b` -> `#define FOO(a,b) ((a)+(b))` – Retired Ninja Jul 19 '22 at 23:17
  • http://eel.is/c++draft/cpp.replace#general-2 – Jeff Garrett Jul 20 '22 at 01:43
  • It's not possible to overload macros (in the sense of having two variants of a macro that take different sets of arguments). If you want overloading, you need proper functions (not preprocessor tricks) - those functions can be standalone or members of a class, depending on requirement. In C++, use of macros (except for a few little things like include guards) are generally discouraged and considered poor practice - best to look for other solutions to a problem before resorting to macros. It usually works out that non-macro solutions are superior to macros by various measures. – Peter Jul 20 '22 at 03:28
  • I'm not sure if this is useful for you, but it would be possible if it's inside a macro argument context. E.g.: `XXX( FOO )` and `XXX( FOO(0,1) )`. – camel-cdr Jul 20 '22 at 19:19

2 Answers2

3

No, macros aren't that clever. They are a simple text substitution, performed by the pre-processor.

At the expense of one more set of brackets you can overload functions though, something like:

int foo () { return 3; }
int foo (int a, int b) { return a + b; }

int main ()
{
    int a = foo (0, 1);
    int b = foo ();
}

And if you want your foos to work with a wider set of types, make them templates.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
  • Re: "a simple text substitution, performed by the pre-processor": The C preprocessor does not perform a "simple text substitution". First, it operates on preprocessor tokens, not text. Second, it has rules about the order of its operations and when replacement tokens are and are not considered for further replacement. Third, it is able to evaluate constant expressions in conditional inclusion. Example: in `#if 1+2` the `1+2` is evaluated according to the rules of constant expressions. Sources: [1](https://stackoverflow.com/q/67848048/1778275), [2](https://stackoverflow.com/a/5022174/1778275). – pmor Jul 24 '22 at 22:42
  • @pmor Conceded. I just wanted to focus on what was important to the OP. – Paul Sanders Jul 25 '22 at 09:41
2

It's not a macro, but looks like it

struct SmartMacro {
    constexpr operator int() const noexcept { return 3; }
    constexpr int operator()(int a, int b) const noexcept { return a + b; }
};
constexpr SmartMacro FOO;

int main() {
    int a = FOO(0,1);
    int b = FOO;
    std::cout << a + b;
    return 0;
}