2013-04-03 29 views
2

Boost MPL web-documentation中,它讨论了将元函数类作为参数传递给boost :: mpl :: transform。在这种情况下,元函数参数应该是某种执行mpl :: ForwardSequence的操作。但是,当使用简单的元函数类将mpl :: transform应用到mpl :: map时,我得到模板错误。 (由于这些错误是相当广泛的,我只包括什么,我相信要在培训相关的位我很乐意,如果请求发布更广泛的错误报告。)boost :: mpl转换操作元函数参数错误

错误:

/usr/include/boost/mpl/aux_/preprocessed/gcc/bind.hpp:207:21: error: no type named  ‘type’ in ‘struct boost::mpl::apply_wrap2<boost::mpl::push_front<mpl_::na, mpl_::na>, boost::mpl::map0<>, boost::mpl::pair<unsigned int, INT32U> >’ 
test_boost_mpl.cpp:106:1: error: ‘from_native_tmap’ was not declared in this scope 

在我的具体情况我的代码如下所示:

/* stl includes */ 
#include <cstdint> 

/* boost includes */ 
#include <boost/type_traits.hpp> 
#include <boost/type_traits/is_same.hpp> 

#include <boost/mpl/at.hpp> 
#include <boost/mpl/map.hpp> 
#include <boost/mpl/empty.hpp> 

#include <boost/mpl/assert.hpp> 
#include <boost/mpl/transform.hpp> 

struct Boolean { 
    enum { tag_value = 0x83 }; 
}; 

struct INT32U { 
    enum { tag_value = 0x84 }; 
}; 

typedef mpl::map 
< 
    mpl::pair<Boolean, bool>, 
    mpl::pair<INT32U, std::uint32_t> 
> to_native_tmap; 

struct swap_f { 
    template<typename PAIR> 
    struct apply { 
    typedef typename mpl::pair<typename PAIR::second, typename PAIR::first> type; 
    }; 
}; 

typedef mpl::transform<to_native_tmap, swap_f>::type from_native_tmap; 

BOOST_MPL_ASSERT((is_same 
        <mpl::at<from_native_tmap, bool>::type, Boolean>)); 
BOOST_MPL_ASSERT((is_same 
        <mpl::at<from_native_tmap, std::uint32_t>::type, INT32U>)); 

int main(void) { return 0; } 

我的意图是在to_native_tmap映射到本地C++类型,然后在from_native_tmap反向映射。

此代码在BOOST_MPL_ASSERT()上失败,或者我尝试实例化to_native_tmap mpl :: map类型。

一个大'谢谢!'任何愿意帮助的人都可以参加。

+0

欢迎来到Stackoverflow!请给出一个最小的[self contained](http://sscce.org/)例子来重现你的问题(在这种情况下显示你的native_to_goose_tmap) – TemplateRex

+0

感谢您的欢迎。我很抱歉没有这样做最初。我是Stack Overflow和Template-Metaprogramming的新手,所以我感谢您的耐心。 – maaronking

+0

不需要道歉,但请务必阅读[常见问题](http://stackoverflow.com/faq) – TemplateRex

回答

5
/* stl includes */ 
#include <cstdint> 

/* boost includes */ 
#include <boost/type_traits.hpp> 
#include <boost/type_traits/is_same.hpp> 

#include <boost/mpl/at.hpp> 
#include <boost/mpl/map.hpp> 
#include <boost/mpl/empty.hpp> 

#include <boost/mpl/assert.hpp> 
#include <boost/mpl/transform.hpp> 

#include <boost/mpl/inserter.hpp> //ADDED 
#include <boost/mpl/insert.hpp> //ADDED 

namespace mpl= boost::mpl; //ADDED 
using boost::is_same; //ADDED 

struct Boolean { 
    enum { tag_value = 0x83 }; 
}; 

struct INT32U { 
    enum { tag_value = 0x84 }; 
}; 

typedef mpl::map 
< 
    mpl::pair<Boolean, bool>, 
    mpl::pair<INT32U, std::uint32_t> 
> to_native_tmap; 

struct swap_f { 
    template<typename PAIR> 
    struct apply { 
    typedef typename mpl::pair<typename PAIR::second, typename PAIR::first> type; 
    }; 
}; 

//The default inserter used by mpl::transform requires that the container have a push_front algorithm 
//This isn't the case for mpl::map (as the assertion in g++4.8.0 reveals: REQUESTED_PUSH_FRONT_SPECIALIZATION_FOR_SEQUENCE_DOES_NOT_EXIST) 
//In this case you need to add a custom inserter 
typedef mpl::inserter<mpl::map0<>, mpl::insert<mpl::_1,mpl::_2> > map_inserter; //ADDED 
typedef mpl::transform<to_native_tmap, swap_f, map_inserter >::type from_native_tmap; //CHANGED 

BOOST_MPL_ASSERT((is_same 
        <mpl::at<from_native_tmap, bool>::type, Boolean>)); 
BOOST_MPL_ASSERT((is_same 
        <mpl::at<from_native_tmap, std::uint32_t>::type, INT32U>)); 

int main(void) { return 0; } 
+0

感谢您花时间回答。我会运行代码并在午餐回来后立即投票/接受。 – maaronking

+0

@maaronking代码在gcc 4.7.2上编译和运行正确,并且可能也在更早的版本上运行(因为Boost.MPL自年龄以来没有真正改变) – TemplateRex

+0

@ user2241635你应该真的得到一个命名的SO帐户,因为如果你可以很容易地回答这些Boost.MPL问题,那么你真的可以在这里帮忙! – TemplateRex