У меня есть код, который использует оператор преобразования шаблона для поиска возвращаемого типа функции, найденной через ADL.
Упрощенный код выглядит так:
#include <type_traits>
template<typename S>
struct probe {
template<typename T, typename U = S, std::enable_if_t<
std::is_same<T&, U>::value &&
!std::is_const<T>::value, int> = 0>
operator T& ();
template<typename T, typename U = S&&, std::enable_if_t<
std::is_same<T&&, U>::value &&
!std::is_const<T>::value, int> = 0>
operator T&& ();
template<typename T, typename U = S, std::enable_if_t<
std::is_same<T const&, U>::value, int> = 0>
operator T const& () const;
template<typename T, typename U = S&&, std::enable_if_t<
std::is_same<T const&&, U>::value, int> = 0>
operator T const&& () const;
};
namespace foo {
struct bar {};
auto find_me(bar const&) -> int { return 0; }
}
int main() {
// That would be inside a template in my code.
find_me(probe<foo::bar>{});
}
В clang 6 и GCC приведенный выше код компилируется. Однако в Clang 7 он больше не компилируется!
Как видите, clang 6 разрешает вызов probe<foo::bar>::operator foo::bar&&<foo::bar, foo::bar&&, 0>()
, но clang 7 терпит неудачу, потому что пытается вызвать probe<foo::bar>::operator const foo::bar&&<const foo::bar, foo::bar&&, 0>()
.
Какой компилятор прав? Какое правило в стандарте для этого? Это новая ошибка Clang или это исправление?
Есть много случаев, которые я хочу проверить. Не только foo::bar
в качестве параметра, но и многие ссылочные типы, такие как этот:
namespace foo {
struct bar {};
auto find_me(bar const&) -> int { return 0; }
auto find_me(bar&&) -> int { return 0; }
auto find_me(bar const&&) -> int { return 0; }
auto find_me(bar&) -> int { return 0; }
}
int main() {
find_me(probe<foo::bar>{});
find_me(probe<foo::bar&>{});
find_me(probe<foo::bar&&>{});
find_me(probe<foo::bar const&>{});
find_me(probe<foo::bar const&&>{});
}
Разрешение на правильный вызов функции важно.
Вот живой пример всех этих случаев, GCC завершается успешно, но clang терпит неудачу: https://godbolt.org/z/yrDFMg< /а>
std::is_same<T const&&, U>
наstd::is_same<T&&, U>
, то будет работать. Я думаю, что это функция С++ 17. godbolt.org/z/ZO7pfC - person Victor Gubin   schedule 04.10.2018