Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

[C++ compile time assertions]: Can we throw a compilation error if some condition is not met?

I wrote a function:

template<int N> void tryHarder() {
    for(int i = 0; i < N; i++) {
        tryOnce();
    }
}

but I only want it to compile if N is in between 0 and 10. Can I do it? How?

like image 819
MciprianM Avatar asked Apr 24 '13 12:04

MciprianM


2 Answers

You can do it with static_assert declaration:

template<int N> void tryHarder() {

    static_assert(N >= 0 && N <= 10, "N out of bounds!");

    for(int i = 0; i < N; i++) {
        tryOnce();
    }
}

This feature is only avaliable since C++11. If you're stuck with C++03, take a look at Boost's static assert macro.

The whole idea of this are nice error messages. If you don't care for those, or can't even affor boost, you could do something as follows:

template<bool B>
struct assert_impl {
    static const int value = 1;
};

template<>
struct assert_impl<false> {
    static const int value = -1;
};

template<bool B>
struct assert {
    // this will attempt to declare an array of negative
    // size if template parameter evaluates to false
    static char arr[assert_impl<B>::value]; 
};

template<int N>
void tryHarder()
{
    assert< N <= 10 >();
}

int main()
{
    tryHarder<5>();  // fine
    tryHarder<15>();  // error, size of array is negative
}
like image 109
jrok Avatar answered Sep 25 '22 08:09

jrok


For pre C++11 compilers, you could implement a template parameter constraint on the non-type parameter N.

For a description of how to do this, please see http://stroustrup.com/bs_faq2.html#constraints

like image 24
rohitsan Avatar answered Sep 24 '22 08:09

rohitsan