Is there a way I can assert that two constant expressions are equal at compile time?
e.g. I want this to cause a compile-time error
enum { foo=263,
Another possibility for Windows is C_ASSERT, which is defined if Windows.h is included.
There is also the trick to use a switch (..)
statement. Kind of old style though. The case entry foo == bar has to be compile time evaluated and if it happens to be false the switch statement will cause an error. The compiler will also reduce it to "nothing".
{
bool x=false;
switch (x) {
case foo == bar:
break;
case false:
// Compile time test that foo == bar
break;
}
I would go for one of the available static_asserts.
But just because I have never tried before I wrote this:
enum { foo=263, bar=264 };
template<bool test>
struct CompileAssert
{
bool assert() {}
};
template<>
struct CompileAssert<false> {}; // fail on false.
int main()
{
CompileAssert<foo != bar>().assert(); // Now I have seen Chad above I like his static
CompileAssert<foo == bar>().assert(); // method better than using a normal method.
} // But I tried zero length arrays first did
// not seem to work
template <int a, int b>
inline void static_assert_equal()
{
typedef char enum_values_must_be_equal[a == b ? 1 : -1];
(void) sizeof(enum_values_must_be_equal);
}
int main()
{
enum { foo = 1, bar = 2, fum = foo };
static_assert_equal<foo, fum>(); // compiles ok
static_assert_equal<foo, bar>(); // fails at compile time
return 0;
}
This derives from the checked_delete idiom.
template<int X, int Y>
struct Check
{
enum { value = false };
};
template<int X>
struct Check<X,X>
{
enum { value = true };
};
I have taken the example of int
. You can change it according to your need. Here is the demo.
Usage:
Check<foo, bar>::value
You can do some preprocessor magic like
#define FOO_VALUE 263
#define BAR_VALUE 264
enum {foo=FOO_VALUE, bar=BAR_VALUE}
#if !(FOO_VALUE == BAR_VALUE)
#error "Not equal"
#endif