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