2015-07-22 2 views
1

Я пытаюсь обернуть голову вокруг большого boost :: hana и попытаться понять, как перевести старый код школьного кортежа.Создайте hana кортеж с неподвижными/noncopyable типами

Возможно, это немного особенное, но у меня есть типы, которые не могут быть скопированы или перемещены, и хотят упаковать их в контейнер. Думайте о политике ...

Я думаю, что я просто не понимаю, как создать ханный кортеж в ценностном мире. То, как я пытаюсь, не работает, потому что make<Tuple>(CompT{}...) нужны типы, которые могут быть скопируемыми или, по крайней мере, перемещаемыми.

Так что, скорее всего, это просто не способ сделать это. Или это ограничение ханы?

Спасибо!

struct NonMoveable 
{ 
    NonMoveable() = default; 
    NonMoveable(const NonMoveable& other) = delete; 

    int val; 
}; 

struct Simple { int val; }; 

template <typename ...CompT> 
struct OldSchoolContainer 
{ 
    template <int I> 
    auto& getComponent() 
    { 
     return std::get<I>(components); 
    } 

    std::tuple<CompT...> components; 
}; 

template <typename ...CompT> 
struct HanaContainer 
{ 
    using Args_t = decltype(make<Tuple>(CompT{}...)); 

    template <int I> 
    auto& getComponent() 
    { 
     return components[int_<I>]; 
    } 

    Args_t components; 
}; 

int main() 
{ 
    OldSchoolContainer<Simple> simpleOsc; 
    static_assert(std::is_same<Simple&, decltype(simpleOsc.getComponent<0>())>::value, ""); 

    HanaContainer<Simple> simpleHanaC; 
    static_assert(std::is_same<Simple&, decltype(simpleHanaC.getComponent<0>())>::value, ""); 


    OldSchoolContainer<NonMoveable> nonmoveableOsc; 
    static_assert(std::is_same<NonMoveable&, decltype(nonmoveableOsc.getComponent<0>())>::value, ""); 

    // !!! this does not compile because hana's tuple closure needs to either move or copy 
    HanaContainer<NonMoveable> nonmoveableHanaC; 
    static_assert(std::is_same<NonMoveable&, decltype(nonmoveableHanaC.getComponent<0>())>::value, ""); 

    return 0; 
} 

ответ

2

Вы можете использовать hana::_tuple<...> тип почти точно так, как std::tuple. Следовательно, следующие работы:

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


struct NonMoveable 
{ 
    NonMoveable() = default; 
    NonMoveable(const NonMoveable& other) = delete; 

    int val; 
}; 

struct Simple { int val; }; 

template <typename ...CompT> 
struct HanaContainer 
{ 
    template <int I> 
    auto& getComponent() 
    { 
     return components[hana::int_<I>]; 
    } 

    hana::_tuple<CompT...> components; 
}; 

int main() 
{ 
    HanaContainer<Simple> simpleHanaC; 
    static_assert(std::is_same<Simple&, decltype(simpleHanaC.getComponent<0>())>::value, ""); 

    HanaContainer<NonMoveable> nonmoveableHanaC; 
    static_assert(std::is_same<NonMoveable&, decltype(nonmoveableHanaC.getComponent<0>())>::value, ""); 

    return 0; 
} 
+0

Это было легко :-) Большое спасибо Луи! Это недостающее звено. Может быть, стоит добавить раздел в вашу замечательную документацию. Когда вы это знаете, это легко найти в примерах, но легко пропустить, поскольку в документах все авто и используются только заводские функции. Отличная работа! –

+0

Без проблем! Я готовлю довольно большое обновление для библиотеки после официального обзора Boost, и это будет документировано лучше. –

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