2

Предположим, что у нас есть что-то вроде этого: Интерфейс для некоторого класса Foo ('FooInterface') и бар класса контейнера, который содержит производные классы из 'FooInterface'.Инициализировать boost :: hana :: tuple с одним аргументом

Теперь я пересылаю список типов производных классов ('FooOne', 'FooTwo') в класс контейнера и хранит их экземпляр в "boost :: hana :: tuple" после вычисление малого типа ('FooTuple').

Теперь как инициализировать элементы кортежа с помощью разыменованного указателя, в зависимости от размера «FooList»?

MCVE (Wandbox)

#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! 

ответ

2

hana::replicate является вашим другом ,

template <typename FooList> 
class Bar { 
    ... 

    using FooTuple = ...; 
    FooTuple foos; 

    Bar() : foos(hana::replicate<hana::tuple_tag>(*this, hana::size_c<N>)) {} 
}; 

Теперь, вы должны быть осторожны, причина, которая будет сделать копию каждого *this при создании кортежа в replicate. Если вы хотите ссылки вместо этого, используйте reference_wrapper как это:

foos(hana::replicate<hana::tuple_tag>(std::ref(*this), hana::size_c<N>)) 

, а затем убедитесь, что конструктор каждой вещи в FooTuple может быть построен из reference_wrapper (что в случае, если они берут ссылку).

+0

hana никогда не перестает удивлять меня :) – Yamahari

1

Не уверен, что это самый простой способ - но вы можете попробовать 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; 
}; 
+0

Я всегда забываю про запятую – Yamahari

+0

Люди всегда забывают о 'hana :: replicate' :-) –

Смежные вопросы