Итак, следующий код строит и запускается под управлением clang ++ (3.8.0), но не работает как в g ++ (6.3. 0) и vC++ (19.10.24903.0). И g ++, и vC++ жалуются на переопределение оператора & &.Перегрузка шаблонов функций в C++ и SFINAE разные поведения в clang ++, g ++, vC++ (режим C++ 14)
Кто-нибудь знает, какой компилятор здесь виноват. Для компиляторов, которые не могут скомпилировать код, какими будут обходные пути для ошибки компиляции?
#include <functional>
#include <iostream>
template <typename T>
struct awaitable
{
friend awaitable<void> operator&&(awaitable a1, awaitable a2)
{
std::cout << "operator&&(awaitable a1, awaitable a2) - T: " << typeid(T).name() << std::endl;
return awaitable<void>{};
}
template <typename U = T, typename std::enable_if<!std::is_same<U, void>::value>::type* = nullptr>
friend awaitable<void> operator&&(awaitable<void> a1, awaitable<U> a2)
{
std::cout << "operator&&(awaitable<void> a1, awaitable<U> a2) - U: " << typeid(T).name() << std::endl;
return awaitable<void>{};
}
template <typename U = T, typename std::enable_if<!std::is_same<U, void>::value>::type* = nullptr>
friend awaitable<void> operator&&(awaitable<U> a1, awaitable<void> a2)
{
std::cout << "operator&&(awaitable<U> a1, awaitable<void> a2) - U: " << typeid(T).name() << std::endl;
return awaitable<void>{};
}
};
int main(int argc, const char * argv[])
{
awaitable<int> a1, a2, a3, a4;
auto ar = a1 && (a1 && a2) && (a2 && a3) && a4;
}
лязг ++: http://coliru.stacked-crooked.com/a/cb01926bbcacdfb0
г ++: http://coliru.stacked-crooked.com/a/73d17a5ae26f22eb
VC++: http://webcompiler.cloudapp.net/
Похоже, что это связано с ошибками компиляции как для g ++, так и для vC++! Но поведение мудрое, ли clang ++ ведет себя правильно или g ++/vC++? – Dejavu
Добавлено несколько подробностей. – rustyx
Значит, вы имеете в виду, что clang является неисправным здесь, не предотвращая противоречивые определения? Или, clang смог каким-то образом «слить» любые противоречивые определения, если они «точно» одинаковы? – Dejavu