C++ Logo

std-discussion

Advanced search

static_assert: substitution failure *IS* an error?

From: Matthew Woehlke <mwoehlke.floss_at_[hidden]>
Date: Thu, 14 Jan 2021 15:18:33 -0500
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?

(See also https://stackoverflow.com/questions/65722107. I didn't check
MSVC, but this happens with both GCC and Clang.)

-- 
Matthew

Received on 2021-01-14 14:18:37