C++ Logo

std-discussion

Advanced search

Re: static_assert: substitution failure *IS* an error?

From: Ville Voutilainen <ville.voutilainen_at_[hidden]>
Date: Thu, 14 Jan 2021 23:06:11 +0200
On Thu, 14 Jan 2021 at 22:19, Matthew Woehlke via Std-Discussion
<std-discussion_at_[hidden]> wrote:
>
> Inspired by the combination of the recent thread on static_assert in
> constexpr and a problem I ran into with real code... Consider the following:
>
> template <typename T>
> void foo(volatile std::atomic<T>*,
> typename std::atomic<T>::value_type)
> {}
>
> template <typename T>
> void foo(std::shared_ptr<T>*, std::shared_ptr<T>)
> {}
>
> std::shared_ptr<std::vector<int>> a;
> foo<std::vector<int>>(&a, a);
>
> (Live demo: https://godbolt.org/z/r6GMhY)
>
> It *looks* like this code ought to compile... and indeed, it compiles
> *if* the template parameter is removed from the invocation of `foo`.
> Without it, however, the static_assert that is tripped trying to
> evaluate std::atomic<T>::value_type for the first overload halts
> compilation, even though the first overload isn't viable *anyway*.
>
> This... seems undesirable, and contrary to SFINAE. Is this intended?

It's not contrary to SFINAE. SFINAE applies in an immediate context,
and a static_assert cannot appear
in an immediate context. The problem here is, as far as I understand
it, that the call with an explicit
template argument triggers instantiation, and that triggers the static_assert.

Received on 2021-01-14 15:06:25