GCC and clang discrepancy in operator lookup

Dear All,

Consider the following code:

struct X{};
struct Y{};

struct B
{
void f(X) { }
void operator{}
};

struct C
{
void f(Y) { }
void operator{}
};

struct D : B, C {};

int main()
{
D d;
d.f(X()); //This is erroneous in all compilers
d[Y()];//this is accepted by clang and MSVC, rejected by GCC
}

What are the rules followed by clang to find the matching operator, that are different for operators and ordinary functions? Can someone elaborate on this difference compared to GCC from the standards perspective?

The original question (link) was in a context where B, C and D are template classes. The same behaviour applies in that case for all compilers, but figuring out the causes now involves dependent name look up. Contributions to that discussion are also welcome.

Daniel