3

I am trying to create a std::vector from a boost::hana::tuple at compile-time like so:

boost::hana::tuple<std::string> namesString{ "Hello", "World" };
std::vector<std::string> namesStringVector{};
while(!(hana::is_empty(namesString)))
{ 
    namesStringVector.emplace_back(hana::front(namesString));
    hana::drop_front(namesString);
}

This clearly doesn't work because the while loop is not run at compile-time.

How do we achieve this effect in Boost::Hana? I.e. what compile-time Hana construct would allow us to perform this cast? I tried doing

    namesStringVector = (std::vector<std::string>)namesString;

and hana::to < std::vector < std::string > >(namesString);

But it tells me there does not exist such a cast in both cases.

Ð..
  • 298
  • 5
  • 18

2 Answers2

4

For starters, boost::hana::tuple<std::string> namesString{ "Hello", "World" }; doesn't make sense because your tuple only has one element but you try to initialize it with two.

Second, it doesn't really make sense to initialize a std::vector from a hana::tuple, since it implies that all the elements of the tuple have the same type. Instead, you should probably be using std::array. Hana is useful when you need heterogeneity (elements with different types), which you don't seem to need here. When you don't need heterogeneity, using std::array or similar tools will be much easier and natural than using Hana.

Louis Dionne
  • 3,104
  • 1
  • 15
  • 35
  • 1
    I agree that they should probably be using `std::array`, but it _also_ implies that all the elements of the tuple have the same type, so your answer doesn't address why it's any more appropriate than `std::vector`. ;-] – ildjarn May 26 '18 at 18:33
4

In addition to the concerns that Louis addressed there are some other issues with how you are trying to use a tuple. Note that a tuple can not have its length or the types within it changed as types are completely immutable in C++ so you have to think in terms of pure functional programming.

Your call to is_empty will always return true, and drop_front can not change the input value, it only returns a new tuple with the front element removed. (in your case it would be tuple<> which is empty).

You might want to rethink your use case for wanting to convert a tuple to vector, but here is an example to hopefully get you started.

#include <boost/hana.hpp>
#include <iostream>
#include <string>
#include <vector>

namespace hana = boost::hana;


template <typename T>
constexpr auto to_vector = [](auto&& ...x) {
        return std::vector<T>{std::forward<decltype(x)>(x)...};
};

int main() {
        auto xs = hana::make_tuple("Hello", "World");

        auto vec = hana::unpack(xs, to_vector<std::string>);

        for (auto const& x : vec) {
                std::cout << x << ' ';
        }

        std::cout << '\n';
}

Notes about list types:

  • std::vector has a run-time length and a single type for all elements.
  • std::array has a compile-time length and a single type for all elements.
  • hana::tuple has a compile-time length and any element can be any
    type.
Jason Rice
  • 1,686
  • 1
  • 12
  • 17