Using `hana::is_valid` fails with const references

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Using `hana::is_valid` fails with const references



I am using hana to determine if an object has a Length member like so:


Length


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:


enable_if


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


T


const T&



So my question is: why does this happen?





Best to include the error messages in your question.
– Ben Voigt
Aug 12 at 4:43





Workaround for clang: std::enable_if_t<has_length(T), void>. However, GCC complains either way.
– Julius
Aug 12 at 5:28


std::enable_if_t<has_length(T), void>





@ildjarn I completely forgot about that.....
– DarthRubik
Aug 12 at 12:11





@ildjarn: If you add both constexpr mine() and constexpr mine(const mine&) then it works.
– Julius
Aug 13 at 6:33


constexpr mine()


constexpr mine(const mine&)





@ildjarn: My comment was not clear enough, sorry: It is not about the constexpr. If you add a copy constructor, then you should also add a default constructor. Then clang compiles the example with auto foo(T).
– Julius
Aug 13 at 11:17



constexpr


auto foo(T)




1 Answer
1



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_.


hana::is_valid


integral_constant


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);






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

make 2 or more post in bootsrap

Store custom data using WC_Cart add_to_cart() method in Woocommerce 3

Firebase Auth - with Email and Password - Check user already registered