Есть класс S с шаблонным оператором <<. Вызывается он из другой шаблонной функции run(), которая инстанциируется в main(). При этом есть перегрузка оператора << с типом MyValue, объявленная до самого main(). То-есть в момент инстанциации (тьфу что за слово такое) шаблона run() видны дефолтный метод (S::operator<<()) и перегруженный и компилятор должен выбрать перегруженный. GCC так и делает, но Clang всё равно игнорирует перегрузку и вызывает дефолтный метод.
При этом если объявить перегруженный метод до объявления шаблона run() (путём простого перемещения #include «run.h» пониже), то Clang начинает работать как и положено, то-есть вызывать перегруженный метод.
Кто прав, кто виноват, и как сие чинить, чтобы был порядок и все компиляторы были счастливы?
run.h
#include <stdio.h>
struct S {
template <typename T>
void operator<<(T) { printf("DEFAULT\n"); }
};
namespace N {
template <typename T>
void run(const T & value) { S s; s << value; }
}
main.cpp (работает в GCC, не работает в clang)
#include "run.h"
struct MyValue {};
namespace N {
void operator<<(S&, MyValue) { printf("OVERLOADED\n"); }
}
int main(int, char**)
{
N::run(MyValue());
return 0;
}
main.cpp (работает и там, и там, #include «run.h» передвинут под перегрузку оператора <<)
#include <stdio.h>
struct S;
struct MyValue {};
namespace N {
void operator<<(S&, MyValue) { printf("OVERLOADED\n"); }
}
#include "run.h"
int main(int, char**)
{
N::run(MyValue());
return 0;
}