c++templatestemplate-specializationstatic-assert

static_assert in function template with non-type template parameter


I have a function template with integer template parameter. I would like to provide an implementation for particular integers only. An attempt to use the function template with another argument should cause a compilation error.

I used static_assert in a way presented below.

#include <type_traits>
#include <iostream>

template <typename T>
struct false_type : public std::false_type {};

template <int T>
void function() {
    static_assert(false_type<decltype(T)>::value, "Error");
};

template <>
void function<1>() {
    std::cout << 1 << std::endl;
}

int main() {
    function<1>();
}

The code works nicely until gcc 9.1 where it gives an error: static assertion failed.

I would like to know if there is a technique that would allow to ahieve my goal and that is compatible with gcc 9.1?


Solution

  • A static_assert whose first argument is a non-dependent false constant is always "ill-formed, no diagnostic required", even in a template that is never instantiated. (So neither g++ nor clang++ is "incorrect" here.) In your function template, T is value-dependent but not type-dependent (its type is always int), so decltype(T) is not dependent, and neither is false_type<int>::value.

    Could you have your false_type simply also take an int as parameter?

    #include <type_traits>
    #include <iostream>
    
    template <int>
    struct false_type : public std::false_type {};
    
    template <int T>
    void function() {
        static_assert(false_type<T>::value, "Error");
    };
    
    template <>
    void function<1>() {
        std::cout << 1 << std::endl;
    }
    
    int main() {
         function<1>();
    }