标签: boost-hana

根据C++中的运行时字符串选择模板

我有一个属性向量,可以包含不同的类型:

class base_attribute_vector; // no template args

template<typename T>
class raw_attribute_vector : public base_attribute_vector;

raw_attribute_vector<int> foo;
raw_attribute_vector<std::string> foo;
Run Code Online (Sandbox Code Playgroud)

根据类型的运行时输入,我想创建适当的数据结构.伪代码:

std::string type("int");
raw_attribute_vector<type> foo;
Run Code Online (Sandbox Code Playgroud)

显然,这失败了.如果出现以下情况,一个简单但丑陋且难以维护的解决方法是运行时切换/链接:

base_attribute_vector *foo;
if(type == "int") foo = new raw_attribute_vector<int>;
else if(type == "string") ...
Run Code Online (Sandbox Code Playgroud)

我读到了有关仿函数的运行时多态性,但发现它对于概念上容易的任务来说非常复杂.

使这项工作最好,最干净的方法是什么?我玩了boost::hana,发现虽然我可以创建从字符串到类型的映射,但查找只能在编译时完成:

auto types = 
hana::make_map(
    hana::make_pair(BOOST_HANA_STRING("int"), hana::type_c<int>),
    hana::make_pair(BOOST_HANA_STRING("string"), hana::type_c<std::string>)
);
Run Code Online (Sandbox Code Playgroud)

所有可能的类型在编译时都是已知的.任何建议都非常感谢.在一个完美的解决方案中,我将在一个地方创建名称 - >类型映射.之后,我会像这样使用它

std::vector<base_attribute_vector*> foo;

foo.push_back(magic::make_templated<raw_attribute_vector, "int">);
foo.push_back(magic::make_templated<raw_attribute_vector, "std::string">);

foo[0]->insert(123);
foo[1]->insert("bla");

foo[0]->print();
foo[1]->print();
Run Code Online (Sandbox Code Playgroud)

这种魔法不需要在编译时发生.我的目标是拥有尽可能可读的代码.

c++ template-meta-programming boost-hana

10
推荐指数
2
解决办法
1959
查看次数

如何用boost.hana解决“常量表达式中不允许读取非constexpr变量'a'”的问题

我在 Boost.hana 中使用 c++17 来编写一些元编程程序。困扰我的一个问题是在像 static_assert 这样的 constexpr 上下文中可以使用什么样的表达式。下面是一个例子:

#include <boost/hana.hpp>

using namespace boost::hana::literals;

template <typename T>
class X {
public:
    T data;

    constexpr explicit X(T x) : data(x) {}

    constexpr T getData() {
        return data;
    }
};


int main() {
    {   // test1
        auto x1 = X(1_c);
        static_assert(x1.data == 1_c);
        static_assert(x1.getData() == 1_c);
    }
    {   //test2.1
        auto x2 = X(boost::hana::make_tuple(1_c, 2_c));
        static_assert(x2.data[0_c] == 1_c);

        // static_assert(x2.getData()[0_c] == 1_c); // read of non-constexpr variable 'x2' is not allowed in a …
Run Code Online (Sandbox Code Playgroud)

c++ boost boost-hana

10
推荐指数
1
解决办法
626
查看次数

嵌套循环使用元编程展开

我有许多嵌套循环,小编号I,J,...在编译时已知,例如

for(int i = 0; i < I; ++i) {
    for(int j = 0; j < J; ++j) {
        // ...
        // do sth with (i,j,...)
    }
}
Run Code Online (Sandbox Code Playgroud)

我需要使用大小I,J,...来展开循环,这样我就可以在编译时使用每个坐标组合.

为了澄清,请考虑以下结构并采用大小为I = 2,J = 3的 2个嵌套循环.

template<int... I>
struct C {
     static void f() {
          // do sth
     }
};
Run Code Online (Sandbox Code Playgroud)

我不能使用索引i,j(类似于上面)来索引结构C,因为它们在编译时是未知的.然而,我想要产生的正是我被允许使用索引的情况,例如

C<0,0>::f();
C<0,1>::f();
C<0,2>::f();
C<1,0>::f();
C<1,1>::f();
C<1,2>::f();
Run Code Online (Sandbox Code Playgroud)

只要产生所有组合,我并不特别关注呼叫生成的顺序.生成机制应该推广到任意数量的嵌套循环.

c++ metaprogramming template-meta-programming c++14 boost-hana

9
推荐指数
1
解决办法
419
查看次数

如何从参数包中定义值类型的元组

我需要构建一个n类型的元组.这n种类型是n种其他类型的值类型.请考虑以下代码段:

#include <boost/hana.hpp>

namespace hana = boost::hana;

template<class... Types>
class CartesianProduct
{
public:
    CartesianProduct(Types... args) : sets(args...) {}

    hana::tuple<Types...> sets;
    hana::tuple<Types...::value_type> combination; // does not work obviously... but wo can this be done?
};
Run Code Online (Sandbox Code Playgroud)

应用程序的目的是这样的:我向这个类传递一个可能不同类型的容器的参数包.该类将这些容器放入元组中sets.该类还有一个字段combination,它是容器传递给类的元素数量的元组.但元素的类型是不同容器的值类型.

然后,该类旨在懒惰地构建传递给它的容器的笛卡尔积,并将当前组合存储在其中combination.但是,我怎样才能以可变方式实际获取容器的值类型?

c++ tuples variadic-templates boost-hana

9
推荐指数
2
解决办法
1419
查看次数

是否可以使用Boost Hana反省方法?

Boost Hana提供了以简单而美观的方式对类成员字段进行内省的能力:

// define:

struct Person {
  std::string name;
  int age;
};

// below could be done inline, but I prefer not polluting the 
// declaration of the struct
BOOST_HANA_ADAPT_STRUCT(not_my_namespace::Person, name, age);

// then:

Person john{"John", 30};
hana::for_each(john, [](auto pair) {
  std::cout << hana::to<char const*>(hana::first(pair)) << ": "
            << hana::second(pair) << std::endl;
});
Run Code Online (Sandbox Code Playgroud)

但是,文档仅提及成员字段.我也想对方法进行反思.我试图用一种方法天真地扩展示例:

struct Foo {
    std::string get_name() const { return "louis"; }
};

BOOST_HANA_ADAPT_STRUCT(::Foo, get_name);
Run Code Online (Sandbox Code Playgroud)

这编译.但是,只要我尝试使用它,使用类似于上面的代码(for_each...),我就会遇到很多编译错误.由于没有显示方法内省的例子,我想知道它是否得到支持.

c++ reflection generic-programming c++14 boost-hana

8
推荐指数
1
解决办法
1374
查看次数

使用lambdas和定点组合器递归访问`std :: variant`

我想使用lambdas和重载创建函数(例如)访问"递归" .std::variantboost::hana::overload


假设我有一个变量类型my_variant,可以存储一个a int,a float或a vector<my_variant>:

struct my_variant_wrapper;

using my_variant = 
    std::variant<int, float, std::vector<my_variant_wrapper>>;

struct my_variant_wrapper 
{
    my_variant _v;
};
Run Code Online (Sandbox Code Playgroud)

(我正在使用包装my_variant_wrapper类来递归地定义变体类型.)


我想以递归方式访问变体,根据存储的类型打印不同的东西.这是一个使用基于访问者的工作示例struct:

struct struct_visitor
{
    void operator()(int x) const { std::cout << x << "i\n"; }
    void operator()(float x) const { std::cout << x << "f\n"; }

    void operator()(const std::vector<my_variant_wrapper>& x) const 
    { 
        for(const auto& y : x) std::visit(*this, y._v); 
    }
};
Run Code Online (Sandbox Code Playgroud)

std::visit使用上述访问者调用打印所需的输出: …

c++ lambda variant boost-hana c++17

8
推荐指数
1
解决办法
1187
查看次数

用于创建integral_constants的aribtrary元组的通用实用程序

利用Scott Schurr,str_const我有一个constexpr字符串.

class StrConst
{
public:
    template<size_t N>
    constexpr StrConst(const char (&str)[N])
        : str_(str)
        , len_(N - 1)
    {
        static_assert(N > 1, "not a string");
    }

    constexpr operator const char*() const
    {
        return str_;
    }

    constexpr size_t size() const
    {
        return len_;
    }

    constexpr char operator[] (size_t i) const
    {
        return i < len_ ? str_[i] : throw std::out_of_range("invalid index");
    }

private:
    const char* const str_;
    const size_t      len_;
};
Run Code Online (Sandbox Code Playgroud)

我有另一个constexpr函数,它从位置n开始返回在字符串中找到的第一个插入符号的位置:

constexpr int …
Run Code Online (Sandbox Code Playgroud)

c++ template-meta-programming c++14 boost-hana

8
推荐指数
1
解决办法
439
查看次数

为什么这个嵌套的lambda不被认为是constexpr?

我正在尝试使用嵌套的constexpr lambdas创建一个curried接口,但编译器不认为它是一个常量表达式.

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

struct C1 {};

template < typename T,
           std::size_t size >
struct Array {};

constexpr auto array_ = [] (auto size) {
      return [=] (auto type) {
        return hana::type_c<Array<typename decltype(type)::type, size()>>;
      };
    };

int main() {

  constexpr auto c1 = hana::type_c<C1>;
  constexpr auto test = hana::type_c<Array<typename decltype(c1)::type, hana::size_c<100>()>>;
  constexpr auto test2 = array_(hana::size_c<100>)(c1);
}
Run Code Online (Sandbox Code Playgroud)

我之前发布了一个问题,因为我找到了一个不同的最小例子,但这还不够.

错误:

test2.cpp: In instantiation of ‘<lambda(auto:1)>::<lambda(auto:2)> [with auto:2 = boost::hana::type_impl<C1>::_; auto:1 = boost::hana::integral_constant<long unsigned int, 100>]’:
test2.cpp:31:54: …
Run Code Online (Sandbox Code Playgroud)

c++ lambda metaprogramming boost-hana c++17

7
推荐指数
2
解决办法
982
查看次数

是否可以使用Boost.Hana反序列化?

我开始使用Boost.Hana,并想知道是否有一种方法可以反序列化为Boost.Hana已知的Struct.我知道将这样的struct序列化为json字符串非常简单,但是我没有找到任何关于反过来的信息.目前是不是可以用Boost.Hana反序列化数据或者我错过了什么?

c++ c++14 boost-hana

6
推荐指数
1
解决办法
1533
查看次数

检查元组类型是否是彼此的子集

假设我有2个未实例化的元组.有没有惯用的方法来检查一组是否是另一组的子集?

如果这需要另一种类型而不是hana::tuple_c,这也很好.实际上,我目前的输入包括std::tuple,但我不能让它以任何方式工作.

代码,它工作(但我觉得应该有类似的东西可能的):

#include <boost/hana.hpp>
using namespace boost;

using SetA = hana::tuple_c<int, char, float>;
using SetB = hana::tuple_c<int, float>;

static_assert(
    hana::is_subset( SetB, SetA ),
    ""
);
Run Code Online (Sandbox Code Playgroud)

我当前的解决方法用于boost::mpl做一个交集,然后比较结果.这有效,但我对一个纯粹的boost::hana解决方案感兴趣:

#include <boost/mpl.hpp>
using namespace boost;

using SetA = mpl::set<int, char, float>;
using SetB = mpl::set<int, float>;

using Intersection = typename mpl::copy_if<
    SetA,
    mpl::has_key< SetB, mpl::_1 >,
    mpl::back_inserter< mpl::vector<> >
>::type;

// since Intersection is a vector, subset also needs vector type
using Subset …
Run Code Online (Sandbox Code Playgroud)

c++ boost-mpl boost-hana

6
推荐指数
1
解决办法
276
查看次数