Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ metaprogramming - generating errors in code

Is there a way that I can create a function that takes an int template parameter, and have that function give a compile time error if the value passed to the function is less than 10?

The following code does not work, but it shows what I want to accomplish:

template <int number1>
void reportErrorIfLessThan10()
{
    #if(number1 < 10)
        #error the number is less than 10
    #endif
}


int maint(int argc, char**argv)
{
   reportErrorIfLessThan10<5>();//report an error!
   reportErrorIfLessThan10<12>();//ok
   return 0;
}
like image 758
Brian R. Bondy Avatar asked Jan 19 '09 22:01

Brian R. Bondy


Video Answer


2 Answers

If you don't want Boost C++ Libraries magic and want bare bones...

template<bool> class static_check
{
};

template<> class static_check<false>
{
private: static_check();
};

#define StaticAssert(test) static_check<(test) != 0>()

Then use StaticAssert. It's a #define for me because I have code that needs to run in a lot of environments where C++ doesn't work right for templates and I need to just back it off to a runtime assert. :(

Also, not the best error messages.

like image 53
Joe Avatar answered Sep 30 '22 05:09

Joe


If for some reason you can't use Boost, this example is trivially written like this:

template <int number1>
void reportErrorIfLessThan10()
{
    typedef char number1_gt_10[number1 > 10 ? 1 : -1];
}


int maint(int argc, char**argv)
{
   reportErrorIfLessThan10<5>();//report an error!
   reportErrorIfLessThan10<12>();//ok
   return 0;
}

Or more generic

#define static_assert(test, message) typedef char static_assert_at_ ## __LINE__[(test) ? 1 : -1];

I'm not concatenating the error message itself, because I feel that static_assert(true, "some message"); is more readable than say static_assert(true, some_message);. However, this does limit the use case to only one assert per line.

like image 43
Jasper Bekkers Avatar answered Sep 30 '22 04:09

Jasper Bekkers