I am looking for a portable one line replacement for the #define
in the following code. The replacement should hide the word APPLE
in the namespace of the Foo
object.
class Foo {
public:
#define APPLE 123
Foo(int a) : a_(a) { }
};
// elsewhere in another file
Foo f(APPLE);
I tried to make this more C++ friendly this, and it worked using the Intel 2017 compiler:
class Foo {
public:
static constexpr int APPLE = 123;
Foo(int a) : a_(a) { }
};
// elsewhere
Foo a(Foo::APPLE);
but it does not work with g++ ((GCC) 6.3.1 20170216), because it gives the error
undefined reference to Foo::APPLE
because it is probably trying to take a reference to APPLE
.
I know I can "fix" the problem by creating definition in a *.cpp file of
constexpr int Foo::APPLE;
but that violates my ideal of having the #define
be replaced by 1 line. My Foo
class is header-file only, and now I would need a cpp
file just for the definition of Foo::APPLE
. I know I could also declare APPLE as a function (static constexpr int APPLE() {return 123;}
) but that is a whole lot more typing in the declaration and at every point of use I need to call the function with ()
.
It seems easier just to use the #define
and be done with it. Non-static const int
works fine, but APPLE
is not usable as an argument to the constructor. Maybe there is a good reason why this is impossible in C++.
Edit: This is not a duplicate of Undefined reference to static constexpr char[]. That question is related to a string and why the particular error message comes up. I am trying to avoid using static linkage all together (I acknowledge in my question that I am aware of how to do static linkage) and I want to do it a "better/cleaner" way, and I see from the Answers that the way that passes my criteria is to use enum
.
You've already listed most alternatives in your question. You'll need consider which approach you want to take:
enum : int { APPLE = 123 };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With