3

I'm trying to access a hana::type from a pair using hana::second...

namespace hana = boost::hana;
using namespace hana::literals;

struct Key {};
struct Foo {};

int main() {

  auto test = hana::make_tuple(
      hana::make_pair(
        hana::type_c<Key>, 
        hana::type_c<Foo>));

  typename decltype(hana::type_c<Foo>)::type  finalTest; //Ok
  typename decltype(hana::second(test[0_c]))::type finalTest2; //Error
}

But I am getting the following compiler error:

stacktest.cpp: In function ‘int main()’:
stacktest.cpp:17:12: error: decltype evaluates to ‘boost::hana::type_impl<Foo>::_&’, which is not a class or enumeration type
   typename decltype(hana::second(test[0_c]))::type finalTest2;

Why does the result of hana::second not return the contained hana::type as expected?

Jason Rice
  • 1,686
  • 1
  • 12
  • 17
Mathieu Van Nevel
  • 1,428
  • 1
  • 10
  • 26
  • I downvoted because this is Stack Overflow and not What's App - Please be more formal in your titles and remove inappropriate language like "_wtf_" – Khalil Khalaf Apr 25 '17 at 18:13
  • Could you please paste the error message and tell us what is the result you expect? – Roberto Apr 25 '17 at 18:13
  • What error do you get? Do `boost::tuple`'s have a `operator[]`? – NathanOliver Apr 25 '17 at 18:13
  • 1
    I hate it when my compiler provides an error message like `//Error` that it inlines into the code. So hard to figure out. – Donnie Apr 25 '17 at 18:16
  • You're right I should have been more explicit about the error sorry – Mathieu Van Nevel Apr 25 '17 at 18:28
  • @Roberto Well I just want it to compile, the error is a variable declaration. – Mathieu Van Nevel Apr 25 '17 at 18:45
  • 3
    The problem is that `hana::second` returns a reference to the contained value. You can wrap it in `hana::typeid_(...)` to get a `hana::type` with ref qualifiers stripped. This could be a good question perhaps if it was formatted a little better. – Jason Rice Apr 25 '17 at 20:59
  • @JasonRice I'm not sure if it was just because I didn't really understood the problem or if I was just too ashamed to ask it sorry. Didn't know about hana::typeid_ thought thanks :) – Mathieu Van Nevel Apr 25 '17 at 21:19
  • @KyleKhalaf I would like to edit and answer the question if that is possible. – Jason Rice Apr 25 '17 at 21:50

1 Answers1

6

The error message states that the decltype is evaluating to boost::hana::type_impl<Foo>::_&, which while a little cryptic looking, you can see by the & at the end that it is a reference to the contained hana::type. Unfortunately the reference will not contain the members that you expect to find in the raw type.

For this hana::type provides a unary operator+ that simply dereferences to the raw type so you can do the following:

typename decltype(+hana::second(test[0_c]))::type finalTest2;

hana::typeid_ works for this as well as it idempotently wraps any value in a hana::type with const and reference qualifiers stripped:

typename decltype(hana::typeid_(hana::second(test[0_c])))::type finalTest2;

It's worth noting that all of the following Hana functions return references:

first, second, at, at_key, and associated operator[].

Jason Rice
  • 1,686
  • 1
  • 12
  • 17
  • The unary operator + is working for me, but when I try to use `hana::typeid_` I get a compiler error that there is no `typeid_` found in namespace hana. Any idea why that would be? I have generically included and I believe that I'm using the latest boost (assuming homebrew has the latest boost because I'm fairly sure cmake is linking against the brew copy). Was this function added or removed at a certain point? – RyanP Jun 06 '17 at 13:35
  • It was added in Boost 1.62. https://github.com/boostorg/hana/commit/edbbffeea4c1b118f4d634098dfa7ec2faa0f95d – Jason Rice Jun 06 '17 at 16:06