问题
Providing a static_assert
in templates are often helpful. In the case where a template shouldn't be instantiated in a certain way at all, I often do this
template<typename T, typename = void>
struct S
{
static_assert(false, "Unconditional error");
static_assert(sizeof(T) != sizeof(T), "Error on instantiation");
};
template<typename T>
struct S<T, std::enable_if_t<std::is_integral_v<T>>>
{
// ...
};
The first static_assert
will fail instantly, even without an instantiation of S
, while the second will succeed if no instantiations will result in the primary template.
The second static_assert
is obviously a tautology, but it "depends" on T
such that the intended effect is achieved. But is this guaranteed? Are compilers allowed to evaluate these tautologies?
回答1:
The relevant rule is [temp.res]/8:
Knowing which names are type names allows the syntax of every template to be checked. The program is ill-formed, no diagnostic required, if:
no valid specialization can be generated for a template or a substatement of a constexpr if statement within a template and the template is not instantiated, or
[...]
Both static_assert
s in the example cause the program to be ill-formed, but no diagnostic is required. Compilers are certainly allowed to evaluate arbitrarily complex expressions to attempt to prove that no valid specialization could be generated, but they are not required that they do so. false
is certainly an easy case to immediately verify, so it's not surprising that it is diagnosed.
A common approach to the desire to always issue a diagnostic is:
// never specialize me!
template <typename T>
struct always_false : std::false_type { };
template <typename T>
constexpr bool always_false_v = always_false<T>::value;
template<typename T, typename = void>
struct S {
static_assert(always_false_v<T>, "Unconditional error");
};
always_false
could hypothetically be specialized on a particular T
to yield true_type
, so there could hypothetically be a valid specialization S<T>
. But don't let anybody actually do that.
来源:https://stackoverflow.com/questions/44345121/are-compilers-allowed-to-evaluate-tautologies-in-static-assert