It sounds like the real problem here is that you have a situation where:
If this is your situation, then I guess you are out of luck, but it's hard for me to imagine how you end up in this situation in the first place. (Why would it be a good idea to have two overloads where one of them takes std::shared_ptr and the other takes std::atomic?)

On Thu, Jan 14, 2021 at 4:06 PM Ville Voutilainen via Std-Discussion <std-discussion@lists.isocpp.org> wrote:
On Thu, 14 Jan 2021 at 22:19, Matthew Woehlke via Std-Discussion
<std-discussion@lists.isocpp.org> 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.
--
Std-Discussion mailing list
Std-Discussion@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion


--
Brian Bi