gct
gct

Reputation: 14573

Does static_assert require use of template parameter?

I'm trying to disallow references with a class I've got and I'm seeing some strange behavior. I've built a toy example that shows what's happening. If I have this:

template <class T>
struct something {
};

template <class T>
struct something<T&> {
    static_assert(false, "reference disallowed with something");
};


int main() {
    something<int>  a; (void)a;
}

Even though I'm not declaring an instance of something with a reference, it still fails:

> g++ -std=c++11 foo.cc -o foo
foo.cc:7:5: error: static assertion failed: reference disallowed with something
     static_assert(false, "reference disallowed with something");
     ^

If I tweak it so that it has to use the template parameter through a proxy class, then it works:

template <class T>
struct something {
};

template <class T>
struct something<T&> {
    template <class TT> struct falsity {
        static const bool value = false;
    };
    static_assert(falsity<T>::value, "reference disallowed with something");
};

int main() {
    something<int>  a; (void)a;
}

Then it works just fine, is this the expected behavior? I would have thought the the static assert would be a member of the class regardless.

Edit: this is gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)

Upvotes: 1

Views: 265

Answers (1)

Praetorian
Praetorian

Reputation: 109119

Your static_assert does not depend on any template parameters and so the compiler does not have to wait until instantiation of the class template to evaluate the statement. Instead it does so during the first phase of two phase name lookup and your code fails to compile.

In your case you can fix the failure by changing the assertion to

static_assert(!std::is_lvalue_reference<T>::value, "reference disallowed with something");

Upvotes: 3

Related Questions