Weird differences between compilers regarding SFINAE and overload resolution
22:09 13 Nov 2025

Here's a snippet that does not depend on any external includes, and behaves differently on msvc/gcc/clang.

I left two alternatives inside main.

It compiles with gcc on both alternatives; does not compile with msvc in neither alternative.

However, it compiles on clang only if I create a named variable, instead of a temporary.

Can anyone explain this behaviour?

I tested with -std=c++23 on clang 21.1.2, but it behaves similarly with other versions.

struct A
{
};

template 
struct B
{
    template 
    struct I
    {
        typedef typename T1::template W::type type;
    };

    // if I remove this template member function, it compiles everywhere
    template 
    typename I::type f(T o)
    {
        return {};
    }

    void f(A)
    {
    }
};

struct C
{
};

int main()
{
    B().f(A{}); // does not compile (clang)
    //B obj; obj.f(A{}); // compiles (clang)
}
c++ templates overloading function-templates-overloading