2016-12-04 5 views
0

나는 boost :: hana에 익숙해 지려고한다. 연습으로 나는 사용자가 제공 한 비교 함수를 사용하여 hana :: tuple에서 중복을 제거하는 함수를 만들고 싶습니다. 내가 직면하고있는 문제는 객체를 객체로 저장하기 위해 hana::type_c을 사용하는 것과 관련이 있습니다. 여기에 내가 hana::type<pair<X,Y>>에서 추출 할 두 번째 요소가 없기 때문에 마지막 줄은 문제를 야기부스트 하나를 사용하여 타이프라이터에서 중복을 제거하는 통일 된 방법

#include <boost/hana/equal.hpp> 
#include <boost/hana/tuple.hpp> 
#include <boost/hana/unpack.hpp> 
#include <boost/hana/pair.hpp> 
#include <boost/hana/any_of.hpp> 
#include <boost/hana/second.hpp> 
#include <boost/hana/fold.hpp> 
#include <boost/hana/core/make.hpp> 
#include <boost/hana/core/tag_of.hpp> 

#include <iostream> 

template <class> 
struct what_is; 

namespace hana = boost::hana; 

// simply push back an element to the sequence 
auto push_back = [](auto seq, auto t) { 

    using namespace boost::hana; 
    return unpack(seq, [&](auto&&... element){return make<typename tag_of<decltype(seq)>::type>(element..., t);}); 
}; 

// this is the main function 
auto remove_duplicates = [](auto seq, auto comp) { 

    using namespace boost::hana; 

    auto f = [&](auto state, auto el){ 
     return if_(any_of(state, partial(comp, el)), 
        [=](){return state;}, 
        [=](){return push_back(state, el);})(); 
    }; 

    return fold(seq, make<typename tag_of<decltype(seq)>::type>(), f); 
}; 

// user-defined comparison function 
// elements are considered equal if only second element of pairs are equal 
auto comp_pair = [](auto&& t1, auto&& t2) { 

    using namespace boost::hana; 
    return equal(second(t1), second(t2)); 
}; 


int main() { 

    auto my_tuple1 = hana::tuple_t<int, float, double, int, float>; 
    auto no_dups1 = remove_duplicates(my_tuple1, hana::equal); // this is fine, decltype(no_dups1) -> tuple< type<int>, type<float>, type<double> > 

    auto my_tuple2 = hana::tuple_t< hana::pair<int, int>, hana::pair<float, int>, hana::pair<float, float> >; 
// auto no_dups2 = remove_duplicates(my_tuple2, comp_pair); // what I want here is tuple< type<pair<int, int>>, type<pair<float, float>> > 
} 

을 것입니다. 이 작업을 수행하려면 tuple< pair<type<int>, type<int>>, pair<type<double>, type<int>>, pair<type<float>, type<double>> >과 같은 매우 못생긴 시퀀스를 만들어야합니다. 당신이 상상할 수 있듯이 이것은 정말로 빠르게 성장할 수 있습니다. 예를 들어 시퀀스가 ​​tuple<int, pair<X,Y>, double, float> 인 경우 등 제가이 문제를 해결할 수있는 획일적 인 방법을 만들 수있는 방법이 있습니까? 나는 MPL/fusion 배경에서 왔고 유형을 감쌀 필요없이 유형을 직접 사용할 수 있습니다. 고마워요

답변

2

퓨전과 달리 Hana는 값을 유형으로 암시 적으로 변환하지 않습니다. 일반적으로이 표현식은 더 표현적인 값 구문을 사용하기 때문에 유용합니다. 다른 한편, 래핑 된 유형을 실제로 추출하려는 사용 사례의 경우 Hana에서 명시 적으로 수행해야하지만 Fusion이 사용자를 위해 수행합니다.

달성하려는 목표에 대해 두 가지 옵션이 있습니다.

template <typename T1, typename U1, typename T2, typename U2> 
constexpr auto comp_pair(hana::basic_type<hana::pair<T1, U1>>, 
         hana::basic_type<hana::pair<T2, U2>>) 
{ 
    return hana::type_c<U1> == hana::type_c<U2>; 
} 

... 

auto no_dups2 = remove_duplicates(my_tuple2, [](auto pair1, auto pair2) { 
    return comp_pair(pair1, pair2); 
}); 

두 번째 솔루션, 좀 더 관용적 찾을 실제로 객체로 유형을 유지하는 것입니다 : 그 쌍 자체를 펼쳤다 있도록 첫 번째 솔루션은 comp_pair 기능을 변경하는 것입니다

// This could arguably be part of Hana, just like we provide tuple_t 
template <typename T, typename U> 
constexpr auto pair_t = hana::make_pair(hana::type_c<T>, hana::type_c<U>); 

auto tuple2 = hana::make_tuple(pair_t<int, int>, pair_t<double, int>, pair_t<float, double>); 
auto nodups2 = remove_duplicates(tuple2, [](auto p1, auto p2) { 
    return hana::second(p1) == hana::second(p2); 
}); 

그러나 말 :

당신은 내가 시퀀스 tuple<int, pair<X,Y>, double, float> 등이 있다면이 예를 들어, 정말 빨리 나쁜 성장할 수있는 상상할 수 있듯이 내가 해제하는 균일 한 방법을 만들 수있는 방법이 있나요 이걸로?

여기를 잘 모르겠습니다. tuple<type<int>, pair<type<X>, type<Y>>, type<double>, type<float>>과 같은 것을 원할 수도 있고이를 달성하기위한 일반적인 방법을 찾고 있습니까? 그렇다면, 나는 당신이하고자하는 일을 성취 할 수있는 더 나은 방법이 있다고 의심한다. 더 많은 문맥을 제공하면 도움을 얻을 수 있습니다.

희망이 도움이됩니다.

+0

감사합니다. 제복으로, 나는'remove_duplicates' 함수가 튜플의 모든 요소가'type '로 감싸 졌다고 가정하기를 원했습니다. 자,이 작업은'my_tuple1'을 사용했을 때 효과가 있었지만'tuple , type >와 완전히 다른 방법으로 래핑 되어야만하는'my_tuple2'는 그렇지 않았습니다. (' 쌍). 'comp_pair' 함수를 생성하는 것이 일반적인 방법이라고 생각합니다. 이 라이브러리를 이용해 주셔서 감사합니다! 굉장한 물건들 – linuxfever