decltype on BOOST_HANA_STRING

306 views Asked by At

My objective is to have a something like the following while writing the string "hello" as a regular string.

struct hello: element<hana::string<'h', 'e', 'l', 'l', 'o'>, std::int64_t>{};

I can have a function make a field of this type

template <typename ValueT, char... Cs>
element<boost::hana::string<Cs...>, ValueT> named_element(boost::hana::string<Cs...>&&, const ValueT& v = ValueT()){
    return element<boost::hana::string<Cs...>, ValueT>(v);
}
// ...
auto hello_e = named_element<int>(BOOST_HANA_STRING("hello"));

But my objective is not to have an object of type element. Instead subclass from it.

I need something like the following, that I can wrap inside a macro.Then I'll use the type hello as template parameter.

struct hello: decltype(named_element<int>(BOOST_HANA_STRING("name"))){};

The above won't compile. But something similar would help.

I am using C++14

2

There are 2 answers

0
ecatmur On

Because BOOST_HANA_STRING uses a lambda internally, it cannot be used in unevaluated context prior to C++20. You will need to give a name to either the string or the field:

auto hello_e = named_element<int>(BOOST_HANA_STRING("hello"));
struct hello: decltype(hello_e){};

If this is not workable, and you cannot upggrade to C++20 but are comfortable depending on a Clang / gcc compiler extension, you can use boost::hana::literals::operator""_s:

#define BOOST_HANA_CONFIG_ENABLE_STRING_UDL 1 // at top of file
using namespace boost::hana::literals;
struct hello: decltype(named_element<int>("name"_s)){};
1
JHBonarius On

I've been looking into this, and the problem seems to be that BOOST_HANA_STRING cannot be used for a c++14 constexpr. Luckily boost is quite amazing, so they've thought about that. Check the HANA string doc.

I've managed to make a compiling example

#include <boost/hana.hpp>
namespace hana = boost::hana;

template <typename T, typename V>
class element{
private:
    V v;
public:
    constexpr element(V const& v) : v(v) {}
};

template <typename ValueT, char... Cs>
constexpr element<hana::string<Cs...>, ValueT> named_element(
    hana::string<Cs...>&&, const ValueT& v = ValueT()){
    return element<hana::string<Cs...>, ValueT>(v);
}

BOOST_HANA_CONSTEXPR_LAMBDA auto hello_e = named_element<int>(BOOST_HANA_STRING("hello"));

struct hello : decltype(hello_e) {
    hello() : decltype(hello_e)(0) {}
};

#include <iostream>

int main()
{
    hello h;
}

godbolt