mardi 19 janvier 2021

static_assert with SFINAE

The standard says in [temp.res]/8:

No diagnostic shall be issued for a template definition for which a valid specialization can be generated. If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required. ... [ Note: If a template is instantiated, errors will be diagnosed according to the other rules in this Standard. Exactly when these errors are diagnosed is a quality of implementation issue. — end note ]

My question is: Does the following count as a valid specialization that can be generated?

#include <type_traits>

template <typename T, typename Enable = void>
class A;

template <typename T>
class A<T, typename std::enable_if<not std::is_same<T, int>::value>::type>
{
public:
    static_assert(std::is_same<T, int>::value, "should not be here!");
};

On the one hand, the static_assert essentially amounts to a static_assert(false, "should not be here"); (we can't both not be an int and be an int at the same time), which isn't allowed. On the other hand, as far as SFINAE is concerned, the type, e.g., A<double> is perfectly well formed and can be generated, but will immediately throw a static assertion failure. This currently works in GCC 8.3, but given the "ill-formed, no diagnostic required" part of the standards quote above, I want to make sure that it actually should work. (Note: work here is defined to mean it throws a static assertion failed if I try to instantiate a A<double> and compiles silently if I don't)

Aucun commentaire:

Enregistrer un commentaire