Search code examples
c++templatesstatic-assertis-same

std::is_same else static assert


I like to to specialize a function with respect to a template type. This works fine with std::is_same.

Now, I like the code to not compile, if a not specialized type is given.

template <typename T>
constexpr double get(const T& item) const {
    if (std::is_same<T, SOME_TYPE>::value)
        return item.get();
    if (std::is_same<T, SOME_OTHER_TYPE>::value)
        return -1.0;
    else {
        // Compile time error, if this branch is created.
        static_assert(false, "Getter not implemented for Type");
        return -1.0;
    }
}

This snippet does not compile, with the error message

error: static assertion failed with "Getter not implemented for Type"

although the function is only instantiated with SOME_TYPE or SOME_OTHER_TYPE.

How can I make sure at compile time, that no others types than SOME_TYPE or SOME_OTHER_TYPE are used?


Solution

  • Simplest way is doing something like this:

    template <typename T>
    constexpr double get(const T& item) const {
        static_assert(
            std::is_same<T, SOME_TYPE>::value || std::is_same<T, SOME_OTHER_TYPE>::value,
            "Getter not implemented for Type");
        if constexpr (std::is_same<T, SOME_TYPE>::value) {
            return item.get();
        } else if constexpr (std::is_same<T, SOME_OTHER_TYPE>::value) {
            return -1.0;
        }
    }
    

    Note that your compiler needs to support C++17 so you can replace if with if constexpr.

    EDIT: The constexpr if is needed here to avoid compilation error if SOME_OTHER_TYPE does not have get() member method. Therefore I have changed the code