I use a const variable in my code. And would like to tell my pre-processor to use it. Namely:
const double x = 1.2;
const bool xIsZero = x==0;
#if xIsZero
...
#endif
But that doesn't work. In C++ 17, if constexpr
doest the trick. But I'm stuck with C++11 for now.
So instead I could use a workaround like:
#define X 1.2
#define xIsZero (x==0)
const double x = X;
#if xIsZero
...
#endif
But I just dislike giving x to a #define, I'd like to give it directly to a const. Is there a way to do that?
If the condition is known at compile-time, you can use overloading to mimic if constexpr
in C++11:
void foo(std::true_type) { // if (xIsZero)
}
void foo(std::false_type) { // if (!xIsZero)
}
constexpr bool xIsZero = ...;
foo(std::integral_constant<bool, xIsZero>{});
As LoPiTaL noted in comments, this is not fully equivalent to if constexpr
, because both foo
s have to compile. This technique becomes important when we work with templates. With plain if
both branches are compiled with the same set of template parameters. With overloading we can effectively discard branches.
For example, this code fails:
template<unsigned int i>
void foo(std::integral_constant<unsigned int, i>) {
if (i > 0) {
consume_positive_i(i);
foo(std::integral_constant<unsigned int, i - 1>{});
} else
consume_zero_i(i);
}
In C++17 it can easily be fixed with if constexpr
:
template<unsigned int i>
void foo(std::integral_constant<unsigned int, i>) {
if constexpr (i > 0) {
consume_positive_i(i);
foo(std::integral_constant<unsigned int, i - 1>{});
} else
consume_zero_i(i);
}
The workaround in C++11 is overloading:
void foo(std::integral_constant<unsigned int, 0>) {
consume_zero_i(i);
}
template<unsigned int i>
void foo(std::integral_constant<unsigned int, i>) {
consume_positive_i(i);
foo(std::integral_constant<unsigned int, i - 1>{});
}
#if
statement is a preprocessor directive. Preprocessor works with your code before the process of compilation. Preprocessor even doesn't know what your code mean, it actually works with text. '#if' checks if argument is true (or defined) and put code into file from #if
- #else
- #endif
statement.
#define
replaces your code for selected. And when you type
#define X 1.2
void f() {
if(X == 0) //...
}
Preprocessor replace this for the
void f() {
if(1.2 == 0) //...
}
const
is a keyword for compiler. Constants are defined in the time of compilation and they are put into special area in memory. So when you type
const double x = 1.2;
void f () {
if(x == 0) //...
}
you call x
from that memory.
So when you're trying to access with preprocessor to the area that compiler deal with, you're getting what you have.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.