用一个参数初始化 boost::hana::tuple
Initialize boost::hana::tuple with one argument
假设我们有这样的东西:一些 class Foo ( 'FooInterface' ) 的接口和一个容器 class Bar 包含派生的 classes 来自 'FooInterface'。
现在我将派生的 classes ( 'FooOne', 'FooTwo' ) 的类型列表转发到容器 class 并存储它们的一个实例在小型计算 ( 'FooTuple' ) 之后的 'boost::hana::tuple' 中。
现在如何根据 'FooList' 的大小使用取消引用的 this 指针初始化元组元素?
#include <iostream>
#include <boost/hana.hpp>
namespace hana = boost::hana;
template <typename FooList>
class Bar;
template <typename FooList>
class FooInterface
{
public:
FooInterface(Bar<FooList>& bar) {}
public:
virtual void foo() = 0;
};
class FooOne;
class FooTwo;
using MyFooList = decltype(hana::tuple_t<FooOne, FooTwo>);
class FooOne final
: public FooInterface<MyFooList>
{
public:
FooOne(Bar<MyFooList>& bar)
: FooInterface(bar)
{}
public:
void foo() override
{
std::cout << "FooOne!\n";
}
};
class FooTwo final
: public FooInterface<MyFooList>
{
public:
FooTwo(Bar<MyFooList>& bar)
: FooInterface(bar)
{}
public:
void foo() override
{
std::cout << "FooTwo!\n";
}
};
template <typename FooList>
class Bar
{
public:
using FooTuple = typename decltype(hana::unpack(FooList(), hana::template_<hana::tuple>))::type;
FooTuple foos{ *this, *this };
};
int main()
{
Bar<MyFooList> b;
b.foos[hana::int_c<0>].foo();
b.foos[hana::int_c<1>].foo();
}
输出:
FooOne!
FooTwo!
不确定这是否是最简单的方法 - 但您可以尝试 std::index_sequence 这样做:
template <typename FooList>
class Bar
{
static constexpr size_t fooListSize = decltype(hana::size(std::declval<FooList>()))::value;
template <std::size_t ...I>
Bar(std::index_sequence<I...>) : foos{(I, *this)...} {}
public:
using FooTuple = typename decltype(hana::unpack(FooList(), hana::template_<hana::tuple>))::type;
Bar() : Bar(std::make_index_sequence<fooListSize>{}) {}
FooTuple foos;
};
hana::replicate
是你的朋友。
template <typename FooList>
class Bar {
...
using FooTuple = ...;
FooTuple foos;
Bar() : foos(hana::replicate<hana::tuple_tag>(*this, hana::size_c<N>)) {}
};
现在,您必须小心,因为在 replicate
中创建元组时会复制每个 *this
。如果您想要引用,请像这样使用 reference_wrapper
:
foos(hana::replicate<hana::tuple_tag>(std::ref(*this), hana::size_c<N>))
然后确保 FooTuple
中的每个事物的构造函数都可以从 reference_wrapper
构造(如果它们采用引用就是这种情况)。
假设我们有这样的东西:一些 class Foo ( 'FooInterface' ) 的接口和一个容器 class Bar 包含派生的 classes 来自 'FooInterface'。
现在我将派生的 classes ( 'FooOne', 'FooTwo' ) 的类型列表转发到容器 class 并存储它们的一个实例在小型计算 ( 'FooTuple' ) 之后的 'boost::hana::tuple' 中。
现在如何根据 'FooList' 的大小使用取消引用的 this 指针初始化元组元素?
#include <iostream>
#include <boost/hana.hpp>
namespace hana = boost::hana;
template <typename FooList>
class Bar;
template <typename FooList>
class FooInterface
{
public:
FooInterface(Bar<FooList>& bar) {}
public:
virtual void foo() = 0;
};
class FooOne;
class FooTwo;
using MyFooList = decltype(hana::tuple_t<FooOne, FooTwo>);
class FooOne final
: public FooInterface<MyFooList>
{
public:
FooOne(Bar<MyFooList>& bar)
: FooInterface(bar)
{}
public:
void foo() override
{
std::cout << "FooOne!\n";
}
};
class FooTwo final
: public FooInterface<MyFooList>
{
public:
FooTwo(Bar<MyFooList>& bar)
: FooInterface(bar)
{}
public:
void foo() override
{
std::cout << "FooTwo!\n";
}
};
template <typename FooList>
class Bar
{
public:
using FooTuple = typename decltype(hana::unpack(FooList(), hana::template_<hana::tuple>))::type;
FooTuple foos{ *this, *this };
};
int main()
{
Bar<MyFooList> b;
b.foos[hana::int_c<0>].foo();
b.foos[hana::int_c<1>].foo();
}
输出:
FooOne!
FooTwo!
不确定这是否是最简单的方法 - 但您可以尝试 std::index_sequence 这样做:
template <typename FooList>
class Bar
{
static constexpr size_t fooListSize = decltype(hana::size(std::declval<FooList>()))::value;
template <std::size_t ...I>
Bar(std::index_sequence<I...>) : foos{(I, *this)...} {}
public:
using FooTuple = typename decltype(hana::unpack(FooList(), hana::template_<hana::tuple>))::type;
Bar() : Bar(std::make_index_sequence<fooListSize>{}) {}
FooTuple foos;
};
hana::replicate
是你的朋友。
template <typename FooList>
class Bar {
...
using FooTuple = ...;
FooTuple foos;
Bar() : foos(hana::replicate<hana::tuple_tag>(*this, hana::size_c<N>)) {}
};
现在,您必须小心,因为在 replicate
中创建元组时会复制每个 *this
。如果您想要引用,请像这样使用 reference_wrapper
:
foos(hana::replicate<hana::tuple_tag>(std::ref(*this), hana::size_c<N>))
然后确保 FooTuple
中的每个事物的构造函数都可以从 reference_wrapper
构造(如果它们采用引用就是这种情况)。