Я работаю над небольшим тестовым проектом с использованием Boost Hana. Я тестирую его на GCC 7.4, Clang и MSVC 19.22. Одна вещь, которую я хотел сделать, это проверить, имеет ли тип определенный оператор равенства.
Для этого я использовал следующий код
auto is_equality_comparable = hana::is_valid([](auto X) -> decltype(hana::traits::declval(X) == hana::traits::declval(X)){});
static_assert(is_equality_comparable(hana::type_c<double>), "What...");
До этого момента все работало корректно со всеми компиляторами.
Следующий шаг - включить эту проверку вКонструкция SFINAE для включения условной компиляции. Поэтому я создал функцию, в которой этот тест используется внутри шаблона enable_if
template<typename T>
typename std::enable_if<is_equality_comparable(hana::type_c<T>), void>::type
TestHana(const T& Obj)
{
/* Do something with == */
}
int
main(int argc, char** argv)
{
double X = 1.3;
TestHana(X);
}
. Этот код прекрасно работает с GCC и Clang, но не работает в MSVC со следующей ошибкой:
error C2100: illegal indirection
note: see reference to function template instantiation 'std::enable_if<'function',void>::type TestAutoConfiguration(const T &)' being compiled
note: see reference to class template instantiation 'std::integral_constant<bool,true>' being compiled
note: see reference to class template instantiation 'std::conjunction<_Traits...>' being compiled
fatal error C1903: unable to recover from previous error(s); stopping compilation
Я боролся в течение нескольких часов, пытаясь понять, в чем проблема, но я не могу понять, делаю ли я что-то неправильно, только перехватывает MSVC или что-то еще. Буду признателен за любой совет.
ОБНОВЛЕНИЕ: Я нашел решение, хотя я не знаю, является ли тот факт, что только MSVC обнаружил предыдущую версию как ошибку, является ошибкой MSVCили из GCC и Clang. Решение заключается в явном доступе к значению интегральной константы в enable_if
template<typename T>
typename std::enable_if<decltype(is_equality_comparable(hana::type_c<T>))::value, void>::type
TestHana(const T& Obj)
{
/* Do something with == */
}