Search code examples
c++templatesc++03static-assert

Why does this static assert not work?


I am trying to use a pre-C++11 static assert. I found this and this question, but somehow I cant get it running:

#define STATIC_ASSERT(x) \
    do { \
        const static char dummy[(x)?1:-1] = {0};\
    } while(0)

struct bar {
    int value;
    template<typename T> void setValue(T x);
};
template<typename T> void bar::setValue(T x) { STATIC_ASSERT(1==0); }
template<> void bar::setValue(int x) { value = x;}

int main(){
    bar b;
    int c = 1;
    b.setValue(c);    
}

Compiling this (gcc) results in

error: size of array 'dummy' is negative

I would expect this error to apprear only if I call setValue with anything other than int. I also tried other proposed solutions, but with more or less the same result: The error is there even if I dont instantiate the template with anything other than int. What am I doing wrong?


Solution

  • If a template is invalid for every instantiation, then the program is ill-formed, no diagnostic required. GCC is therefore perfectly valid in giving you an error here, as the primary template for setValue is invalid no matter what the template argument is.

    The way to solve this issue is to make the STATIC_ASSERT expression dependent on a template parameter. One option is to make a dependent_false template class, like this:

    template <typename T> struct dependent_false 
    { const static bool value = false; };
    
    template<typename T> void bar::setValue(T x) 
    { STATIC_ASSERT(dependent_false<T>::value); }