mapbox/variant

Checks Concepts - Error Messages

Opened this issue · 0 comments

While working on #126 I tested what happens if Ts are not Hashable.
Turns out the error messages are pretty bad - as expected.

This is true for all features relying on the underlying types. Could e.g. be comparing variants for equality and then variant's operator== fails to compile since the underlying types are not comparable.

Here is what we could do: emulate Concepts via Expression SFINAE and use them to provide beautiful error messages. Here is a first example of how this could look on the Hashable side:

struct hasher
{
    template <typename T, typename = void>
    struct is_hashable : std::false_type {};

    template <typename T>
    struct is_hashable<T, decltype((void)std::hash<T>{}(std::declval<T>()))> : std::true_type {};

    template <typename T>
    std::size_t operator()(const T& hashable) const
    {
        static_assert(is_hashable<T>::value, "type is not hashable");
        return std::hash<T>{}(hashable);
    }
};

Now error messages are down to

./include/mapbox/variant.hpp:547:9: error: static assertion failed: type is not hashable
     static_assert(is_hashable<T>::value, "type is not hashable");

instead of coming from deep down in the stdlib's btree implementation just because you tried to put a variant into an unordered set. Similarly this would work for equality etc.

Note: I'm not up to date on how far Expression SFINAE support is in Microsoft's VS, a couple of years ago is was a no go. Just something to be aware of. On the GCC / Clang side we're good.