问题
Consider the following class:
class Foo
{
public:
#ifdef CONDITION
int x = 0;
#endif
int y;
int foo() {
#ifdef CONDITION
return ++x;
#else
return 0;
#endif
}
}
int x
only exists when I define CONDITION
- either through a #define CONDITION
or as a preprocessor definition (-D CONDITION
)
This has the neat advantage that I can't compile it I use x
by mistake somewhere when CONDITION
isn't defined.
For example: If, by mistake, I write something like:
Foo f;
f.x = 10;
This will not be allowed to compile when I'm missing -D CONDITION
However, we get all sorts of nasty problems when class Foo
is declared in a header that is used by multiple projects, where preprocessor definitions differ:
The offset of y
within Foo
will be different, resulting in different interpretations of how an object of Foo
looks.
The question:
Is there some way in which I can declare x
for anyone using Foo
, but still get some sort of compiler warning/error when I try to use it without defining CONDITION
?
回答1:
Don't make definitions that are visible in headers conditional on macro definitions.
If you need to add different members conditionally, then you must hide those members from the user of the class. This can be achieved with the PIMPL pattern.
回答2:
What you want is ODR violation. A cleaner approach would have been making CONDITION
a bool
template parameter.
But if you take this risk, you can take it in reduced form with difference of x
only in attribute:
class Foo
{
#ifndef CONDITION
[[deprecated("Don'u use with [[condition]] defined")]]
#endif
int x = 0;
int y;
}
来源:https://stackoverflow.com/questions/62996598/allow-use-of-member-variable-depending-on-preprocessor-directives