Compile-time assertion?

后端 未结 12 982
春和景丽
春和景丽 2020-11-27 06:09

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,          


        
相关标签:
12条回答
  • 2020-11-27 06:13

    Another possibility for Windows is C_ASSERT, which is defined if Windows.h is included.

    0 讨论(0)
  • 2020-11-27 06:13

    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;
    }
    
    0 讨论(0)
  • 2020-11-27 06:16

    I would go for one of the available static_asserts.

    • boost::static_assert
    • C++0x static_assert

    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
    
    0 讨论(0)
  • 2020-11-27 06:19
    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.

    0 讨论(0)
  • 2020-11-27 06:19
    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
    
    0 讨论(0)
  • 2020-11-27 06:20

    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
    
    0 讨论(0)
提交回复
热议问题