One of the weirder corner cases of C is that functions can be declared within other functions, e.g.
void foo(void)
{
void bar(void); // Behaves as if this was written above void foo(void)
bar();
}
This has carried through into C++, at least for most functions. Clang doesn't appear to recognise the pattern if the function in question happens to be called operator==.
struct foo
{
int value;
};
struct bar
{
foo value;
};
bool wot(const bar &x, const bar &y)
{
bool eq(const foo &, const foo &); // Declare function eq
bool operator==(const foo &, const foo &); // Declare function operator==
bool func = eq(x.value, y.value); // This line compiles fine
bool call = operator==(x.value, y.value); // Also OK - thanks user657267!
bool op = x.value == y.value; // This one doesn't
return func && call && op;
}
bool test()
{
bar a;
bar b;
return wot(a,b);
}
GCC and ICC compile this fine. Checking name mangling in the object suggests the operator== has been declared with the right types. Clang (I tried up to 3.8) errors:
error: invalid operands to binary expression
('const foo' and 'const foo')
bool op = x.value == y.value;
~~~~~~~ ^ ~~~~~~~
Unless the declaration is moved to directly above the function, in which case Clang is happy too:
bool operator==(const foo &, const foo &);
bool wot(const bar &x, const bar &y)
{
return x.value == y.value; // fine
}
I can't use this workaround as the "real world" case that provoked this question involves layers of templates, meaning I only know the type name "foo" within the function declaration.
I believe this is a bug in Clang - is there special handling of operatorX free functions which prohibits declaring them within a function?
bool op = operator==(x.value, y.value);
, for whatever reason clang's operator lookup is failing to find the block scope declaration. – Novela@b
causes a non-member candidateoperator@(a,b)
before anything else happens , so the fact that the second form works but the first doesn't strongly suggests a bug – Gardiner