Я просматриваю примеры страницы справки потрясающей библиотеки boost::hana и не могу заставить пример самоанализа работать правильно.
Этот код предназначен для проверки во время компиляции, имеет ли объект определенную функцию-член или нет, а затем использует эту функцию-член или делает что-то по умолчанию.
Итак, я объявил эти два типа:
struct WithoutToString
{ };
struct WithToString
{
std::string toString()
{
return "implements toString()";
}
};
Это 1-я версия проверки с использованием hana::is_valid
:
auto has_toString = hana::is_valid([] (auto&& obj) -> decltype(obj.toString()) { });
template <typename T>
std::string optionalToString1(T const& obj)
{
return hana::if_(has_toString(obj),
[] (auto& x) { return x.toString(); },
[] (auto& x) { return "toString not defined"; }
)(obj);
}
Это 2-я версия проверки с использованием hana::sfinae
:
template <typename T>
std::string optionalToString2(T const& obj)
{
auto maybeToString = hana::sfinae([](auto&& x) -> decltype(x.toString())
{
return x.toString();
});
return maybeToString(obj).value_or("toString not defined");
}
Используя обе версии, как это...
int main()
{
WithToString obj;
std::cout << optionalToString1(obj);
std::cout << optionalToString2(obj);
return 0;
}
... всегда показывает "toString не определен" вместо "реализует toString()".
Примечание: проверка obj
на static_assert(has_toString(obj), "Does not implement toString().");
показывает правильное поведение.
Я что-то упускаю? Или это проблема компилятора (clang 5.0.1) или библиотеки (boost 1.66)?
Спасибо.