Enforce template type through static_assert

c++, static-assert, template-specialization, templates

Solution

I figured out a better solution for this problem by combining the answers and comments here.

I can define a static type checker like so:

template <class A, class B>
struct CheckTypes
{
    static const bool value = false;
};

template <class A>
struct CheckTypes<A, A>
{
    static const bool value = true;
};

Not sure if such a struct already exists in the standard library. Anyways, then in Foo, I can check for types and sizes using:

static_assert((sizeof(T) == sizeof(long) || sizeof(T) == sizeof(int)) && !CheckTypes<T, float>::value, "Error!");

Problem

I'm trying to understand the usefulness of `static_assert`, and I want to know if it can help me in enforcing a design, and if so, how. I have a general template class that hides its own implementation inside another template class which is partially specialized based on the size of the template type. Here's a brief outline of this design: ``` template <class T, size_t S = sizeof(T)> struct Helper; template <class T> struct Helper<T, sizeof(long)> { static T bar(); }; // ... other specializations ... template <class T> class Foo { public: T bar() { return Helper<T>::bar(); } }; ``` Foo is only supported if size of `T` is supported by a specialization of Helper. For example, `Foo<long>` and `Foo<unsigned long>` are both supported. However, suppose the user tries to construct a `Foo<bool>`. Normally, this would generate errors because the specialization of Helper for `bool` isn't defined, which is intended behaviour. Is there any way to use `static_assert` in this design to provide more helpful errors to the user of this interface? Additionally, I'd like to also restric the user from using a specific type, even though the size might be correct. For example, `Foo<float>` shouldn't be allowed. Right now, the only way I know of enforcing this is through a bold comment in the documentation. :)

Original source