2016-07-06 27 views
4

我試圖讓使用融合點和我有這個簡單的例子難倒:升壓變換融合式操作和as_vector

#include <boost/fusion/include/is_sequence.hpp> 
#include <boost/fusion/include/as_vector.hpp> 
#include <boost/fusion/include/make_vector.hpp> 
#include <boost/fusion/include/transform.hpp> 

template< typename T > 
struct S { 
    typedef T type; 
}; 

struct S_f { 
    template< typename T > 
    struct result { 
     typedef typename T::type type; 
    }; 
}; 

int main() { 
    using namespace boost; 
    typedef fusion::vector<S<int>> from_type; 
    BOOST_MPL_ASSERT((fusion::traits::is_sequence< fusion::vector<int> >)); 

    typedef fusion::result_of::transform< from_type, S_f >::type to_type; 
    BOOST_MPL_ASSERT((fusion::traits::is_sequence<to_type>)); 

    typedef fusion::result_of::as_vector<to_type>::type value_type; // error 
} 

的斷言通但VALUE_TYPE typedef的失敗,下面的錯誤。我無法爲代碼和文檔之間的任何差異提供資金,也無法在其他地方在stackoverflow或boost郵件列表中找到補救措施。

AFAICT代碼是正確的:應用變換元函數的結果是transform_view,而transform_view是一個序列,如傳遞斷言所示。然而,在transform_view上應用as_vector元函數失敗。是什麼賦予了?!

任何幫助表示讚賞。我對mpl的混合沒有興趣。我知道我可以繞過MPL,並在SO上提出一些關於類型操縱的融合問題,這些問題都有支持MPL的答案。根據文檔,我不需要MPL。

clang++ -std=c++1z -c t.cpp 
In file included from main.cpp:4: 
In file included from /usr/local/include/boost/fusion/include/transform.hpp:11: 
In file included from /usr/local/include/boost/fusion/algorithm/transformation/transform.hpp:11: 
In file included from /usr/local/include/boost/fusion/view/transform_view/transform_view.hpp:15: 
In file included from /usr/local/include/boost/fusion/view/transform_view/transform_view_iterator.hpp:18: 
/usr/local/include/boost/fusion/view/transform_view/detail/value_of_impl.hpp:37:74: error: no type named 'type' in 'boost::mpl::apply<boost::fusion::detail::apply_transform_result<S_f>, S<int>, mpl_::na, mpl_::na, mpl_::na, mpl_::na>' 
       typedef typename mpl::apply<transform_type, value_type>::type type; 
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~ 
/usr/local/include/boost/fusion/iterator/value_of.hpp:52:15: note: in instantiation of template class 'boost::fusion::extension::value_of_impl<boost::fusion::transform_view_iterator_tag>::apply<boost::fusion::transform_view_iterator<boost::fusion::vector_iterator<boost::fusion::vector<S<int>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, 0>, S_f> >' requested here 
      : extension::value_of_impl<typename detail::tag_of<Iterator>::type>:: 
      ^
/usr/local/include/boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector10.hpp:19:49: note: in instantiation of template class 'boost::fusion::result_of::value_of<boost::fusion::transform_view_iterator<boost::fusion::vector_iterator<boost::fusion::vector<S<int>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, 0>, S_f> >' requested here 
      typedef typename fusion::result_of::value_of<I0>::type T0; 
               ^
/usr/local/include/boost/fusion/container/vector/convert.hpp:26:17: note: in instantiation of template class 'boost::fusion::detail::barrier::as_vector<1>::apply<boost::fusion::transform_view_iterator<boost::fusion::vector_iterator<boost::fusion::vector<S<int>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, 0>, S_f> >' requested here 
       template apply<typename result_of::begin<Sequence>::type>::type 
       ^
main.cpp:26:32: note: in instantiation of template class 'boost::fusion::result_of::as_vector<boost::fusion::transform_view<boost::fusion::vector<S<int>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, S_f, boost::fusion::void_> >' requested here 
    typedef fusion::result_of::as_vector<to_type>::type value_type; // error 
          ^
1 error generated. 

回答

5

模板元編程的問題在於,當您未能滿足元函數的前提條件時,會出現很多無意義的錯誤。 transform的要求是F是一元Polymorphic Function Object。對文檔中內容的解釋有點弱,但可以從示例中看出:這是一個對象,您可以使用參數調用。也就是說,result_of<F(T)>::type需要格式良好。

什麼你傳遞給transform是:

struct S_f { 
    template< typename T > 
    struct result { 
     typedef typename T::type type; 
    }; 
}; 

這不是一個多態函數對象。它也不是一個元函數類。這不是Boost.Fusion也不是Boost.MPL能夠理解的。這特別令人困惑的是transform<>元函數是懶惰 - 所以看起來你正確地做了那部分。只有在as_vector<>中,實際上應用了轉換,所以它看起來就是失敗點的位置。

要將其轉換爲一個多態函數對象,只是改變了嵌套result類模板爲呼叫運營商:

struct S_f { 
    template< typename T > 
    typename T::type operator()(T); 
}; 

沒有定義必要的,因爲你沒有實際調用它。使用該修補程序,您的代碼將被編譯。