Один из странных угловых случаев C состоит в том, что функции могут быть объявлены в рамках других функций, например.
void foo(void)
{
void bar(void); // Behaves as if this was written above void foo(void)
bar();
}
Это перенесено на С++, по крайней мере для большинства функций. Clang, по-видимому, не распознает шаблон, если рассматриваемая функция называется оператором ==.
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 и ICC составляют этот штраф. Проверка имени в объекте предполагает, что оператор == был объявлен с правильными типами. Clang (я пробовал до 3.8):
error: invalid operands to binary expression
('const foo' and 'const foo')
bool op = x.value == y.value;
~~~~~~~ ^ ~~~~~~~
Если объявление не будет перемещено непосредственно над функцией, в этом случае Clang также будет счастлив:
bool operator==(const foo &, const foo &);
bool wot(const bar &x, const bar &y)
{
return x.value == y.value; // fine
}
Я не могу использовать это обходное решение, так как случай "реального мира", вызвавший этот вопрос, включает в себя слои шаблонов, то есть я знаю только имя типа "foo" в объявлении функции.
Я считаю, что это ошибка в Clang - есть ли специальная обработка бесплатных функций operatorX, которая запрещает объявление их внутри функции?