我有一个属性向量,可以包含不同的类型:
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)
这种魔法不需要在编译时发生.我的目标是拥有尽可能可读的代码.
我在 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) 我有许多嵌套循环,小编号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
我需要构建一个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.但是,我怎样才能以可变方式实际获取容器的值类型?
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...),我就会遇到很多编译错误.由于没有显示方法内省的例子,我想知道它是否得到支持.
我想使用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使用上述访问者调用打印所需的输出: …
利用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) 我正在尝试使用嵌套的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) 我开始使用Boost.Hana,并想知道是否有一种方法可以反序列化为Boost.Hana已知的Struct.我知道将这样的struct序列化为json字符串非常简单,但是我没有找到任何关于反过来的信息.目前是不是可以用Boost.Hana反序列化数据或者我错过了什么?
假设我有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) boost-hana ×10
c++ ×10
c++14 ×4
c++17 ×2
lambda ×2
boost ×1
boost-mpl ×1
reflection ×1
tuples ×1
variant ×1