Compile-time assertion?

后端 未结 12 1020
春和景丽
春和景丽 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:22

    Similar to iammillind's solution, which was unfortunately one only useful at runtime:

    template 
    class VALUES { 
    };
    
    // specialization to provide safe passage for equal values        
    template 
    class VALUES {
    public:
       static void MY_VALUES_ARE_EQUAL() {}
    };
    
    
    #define ASSERT_EQUALITY(a, b)    \
    {    \
       typedef VALUES COMPILE_TIME_ASSERTION;       \
       COMPILE_TIME_ASSERTION::VALUES_ARE_EQUAL();     \
    }
    
    int main() {
       ASSERT_EQUALITY(1, 1);    // compiles just fine
       ASSERT_EQUALITY(1, 2);    // ERROR!
       // . . . 
     }
    

    The nice thing about this is that it provides a nice compiler message. My compiler tells me the following:

    ‘VALUES_ARE_EQUAL’ is not a member of ‘COMPILE_TIME_ASSERTION {aka VALUES<1, 2>}’

    You don't need the typedef. Without:

    'VALUES_ARE_EQUAL' is not a member of 'VALUES<1, 2>'

    Of course, there are a bunch of other ways to generate helpful messages. For giggles:

    // these give use some tips in the compiler warnings
    class COMPILE_TIME_EQUALITY_ASSERTION {} compiler_message; 
    class EQUAL_VALUES_ONLY_PLEASE {};
    
    
    template 
    class VALUES {
    public:
       static void AreEqual(EQUAL_VALUES_ONLY_PLEASE) {}
    };
    
    template 
    class VALUES
    {
    public:
       static void AreEqual(COMPILE_TIME_EQUALITY_ASSERTION) {}
    };
    
    
    #define ASSERT_EQUALITY(a, b)                                   \
    {                                                               \
       VALUES::AreEqual(compiler_message);                             \
    }
    
    int main() {
        ASSERT_EQUALITY(1, 1) // a-okay
        ASSERT_EQUALITY(1, 2) // ERROR!
    }
    

    I get the following compiler errors:

    no matching function for call to:
    ‘VALUES<1,2>::AreEqual(COMPILE_TIME_EQUALITY_ASSERTION&)' 
    candidate is:
    static void VALUES<\A, B>::AreEqual(EQUAL_VALUES_ONLY_PLEASE) [with int A = 1, int B = 2]
    

    combinations of static member functions/constructors/field assignment/privacy and template specifications can yield different results perhaps more appropriate for your situation.

提交回复
热议问题