I am using hana to determine if an object has a Length
member like so:
using boost::hana::is_valid;
static const auto has_length
= is_valid([](const auto& obj)
-> decltype(obj.Length(),void()) {});
This works fine....I can do static asserts with it all day to my hearts content. So the next step is logically to enable_if
a function:
template<typename T>
auto foo(T t) -> std::enable_if_t<has_length(t), void>
{
}
struct mine
{
int Length() const { return 0; }
};
int main()
{
foo(mine{});
}
This works just fine....but as soon as I change the T
to const T&
, we get errors that there is no suitable overload: godbolt
So my question is: why does this happen?
The problem is that calling a function with a reference that is not constexpr is not constexpr. This is where hana::is_valid
is useful because it returns an integral_constant
-like value that contains a static constexpr boolean so we can just look at the return type. See bool_
.
Here is an example:
#include <boost/hana.hpp>
#include <type_traits>
namespace hana = boost::hana;
static auto has_length = hana::is_valid([](auto&& t)
-> decltype(t.Length()) { });
template <typename T>
auto foo(T const& t)
-> std::enable_if_t<decltype(has_length(t)){}, void>
// ^-- notice the return type
// is a boolean integral constant
{ }
struct mine
{
int Length() const { return 0; }
};
int main()
{
foo(mine{});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With