200分,送!(解决了)

yshuise 2009-05-07 08:30:15
#include "stdafx.h"
#include <iostream>
#include <string>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/erase.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/front.hpp>

using std::string;
using std::cout;
using std::endl;
using boost::mpl::at ;
using boost::mpl::int_;
using boost::mpl::pop_front;
using boost::mpl::vector;
using boost::mpl::deref;
using boost::mpl::begin;
using boost::mpl::front;


struct NullType{ };

template<int N>
struct Int2Type
{
enum{ vaule = N };
};

template <class T>
struct Holder{
typename T vaule;
};
template <class TList, template<class> class Unit>
class GenScatterHierarchy;//主模板

template<class T1, class T2, template<class> class Unit>
class GenScatterHierarchy<typename begin<vector<T1,T2>>::type , Unit>//对主模进行特化。
: public GenScatterHierarchy<typename front<vector<T1,T2>>::type, Unit>
, public GenScatterHierarchy<typename pop_front<vector<T1,T2>>::type, Unit>
{

};

template<class ATomicType, template<class> class Unit>
class GenScatterHierarchy : public Unit<ATomicType>
{

};

template<template<class> class Unit>
class GenScatterHierarchy<NullType, Unit>{

};



// template<class TList, template<class> class Unit>
// Unit< at<TList, int_<0>>>& FieldHelper(
// GenScatterHierarchy<TList,Unit>& obj, Int2Type<0> )
// {
// GenScatterHierarchy<at<TList, int_<0>>, Unit>& leftBase = obj;
// return leftBase;
// };
//
// template<int i, class TList, template<class> class Unit>
// Unit< at<TList, int_<i>>>& FieldHelper(
// GenScatterHierarchy<TList, Unit>& obj, Int2Type<i>)
// {
// GenScatterHierarchy<pop_front<TList>, Unit>& rightBase = obj;
// return FieldHelper(rightBase, Int2Type<i-1>());
// }
//
// template <int i, class TList, template<class> class Unit>
// Unit< at<TList,int_<i>>>&
// Field (GenScatterHierarchy<TList, Unit>& obj)
// {
// return FieldHelper(obj, Int2Type<i>() );
// }


int _tmain(int argc, _TCHAR* argv[])
{

//typedef GenScatterHierarchy<vector<int, string>, Holder> Info;
// Info obj;
// int b = (static_cast<Holder<int>&>(obj)).vaule;//这种递归仍是可疑,关键是模板特化仍不对。
//deref<begin<vector<int>::type>::type>::type a=9;
//cout<<a<<endl;
return 0;

}

f:\documents and settings\administrator\my documents\visual studio 2005\projects\csdn\csdn\csdn.cpp(48) : error C2764: 'T1' : template parameter not used or deducible in partial specialization 'GenScatterHierarchy<begin<boost::mpl::vector<T0,T1,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na>>::type,Unit>'
f:\documents and settings\administrator\my documents\visual studio 2005\projects\csdn\csdn\csdn.cpp(48) : error C2764: 'T2' : template parameter not used or deducible in partial specialization 'GenScatterHierarchy<begin<boost::mpl::vector<T0,T1,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na>>::type,Unit>'
...全文
596 127 打赏 收藏 转发到动态 举报
写回复
用AI写文章
127 条回复
切换为时间正序
请发表友善的回复…
发表回复
逆风向前进 2009-05-10
  • 打赏
  • 举报
回复
楼主什么解决了?
flora186 2009-05-10
  • 打赏
  • 举报
回复
也让我先得一分吧
vbcpascal 2009-05-10
  • 打赏
  • 举报
回复
up,jf
strive0 2009-05-10
  • 打赏
  • 举报
回复
jf~~~
yshuise 2009-05-09
  • 打赏
  • 举报
回复
感谢各位大力支持。包括deng2000
yshuise 2009-05-09
  • 打赏
  • 举报
回复
终于成功了!
#include "stdafx.h"
#include <iostream>
#include <string>
#include <typeinfo>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/erase.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/back.hpp>

using std::type_info;
using std::string;
using std::cout;
using std::endl;
using boost::mpl::at ;
using boost::mpl::int_;
using boost::mpl::pop_front;
using boost::mpl::vector;
using boost::mpl::deref;
using boost::mpl::begin;
using boost::mpl::front;
using boost::mpl::back;


struct NullType{ };

template<int N>
struct Int2Type
{
enum{ vaule = N };
};

template <class T>
struct Holder{
typename T vaule;
};
//允许模板参数的最大值为10。 也可以自己嵌套写,用vector, 这样可以写更多的参数。
template <typename T1, typename T2 = NullType, typename T3 = NullType, typename T4= NullType,
typename T5 = NullType, typename T6 = NullType, typename T7 = NullType,typename T8= NullType,
typename T9 = NullType, typename T10 = NullType>
struct my_vector{
typedef vector<T1,vector<T2,vector<T3,vector<T4,vector<T5,vector<T6, vector<T7, vector<T8,vector<T9,vector<T10,NullType>>>>>>>>>> type;
};

template <typename T1>
struct my_vector<T1>{
typedef vector<T1,NullType> type;

};

template <typename T1, typename T2>
struct my_vector<T1,T2>{
typedef vector<T1,vector<T2,NullType>> type;

};

template <typename T1, typename T2, typename T3>
struct my_vector<T1,T2,T3>{
typedef vector<T1,vector<T2,vector<T3,NullType>>> type;

};

template <typename T1, typename T2, typename T3, typename T4>
struct my_vector<T1,T2,T3,T4>{
typedef vector<T1,vector<T2,vector<T3,vector<T4,NullType>>>> type;

};

template <typename T1, typename T2, typename T3, typename T4, typename T5>
struct my_vector<T1,T2,T3,T4,T5>{
typedef vector<T1,vector<T2,vector<T3,vector<T4,vector<T5,NullType>>>>> type;

};
template <typename T1, typename T2, typename T3, typename T4, typename T5,typename T6>
struct my_vector<T1,T2,T3,T4,T5,T6>{
typedef vector<T1,vector<T2,vector<T3,vector<T4,vector<T5,vector<T6, NullType>>>>>> type;

};
template <typename T1, typename T2, typename T3, typename T4, typename T5,typename T6,typename T7>
struct my_vector<T1,T2,T3,T4,T5,T6,T7>{
typedef vector<T1,vector<T2,vector<T3,vector<T4,vector<T5,vector<T6, vector<T7, NullType>>>>>>> type;

};
template <typename T1, typename T2, typename T3, typename T4, typename T5,typename T6,typename T7,typename T8>
struct my_vector<T1,T2,T3,T4,T5,T6,T7,T8>{
typedef vector<T1,vector<T2,vector<T3,vector<T4,vector<T5,vector<T6, vector<T7, vector<T8,NullType>>>>>>>> type;

};
template <typename T1, typename T2, typename T3, typename T4, typename T5,typename T6,typename T7,typename T8,typename T9>
struct my_vector<T1,T2,T3,T4,T5,T6,T7,T8,T9>{
typedef vector<T1,vector<T2,vector<T3,vector<T4,vector<T5,vector<T6, vector<T7, vector<T8,vector<T9,NullType>>>>>>>>> type;

};

template<class TList, unsigned int index> struct TypeAt;

template <class Head, class Tail>
struct TypeAt<vector<Head, Tail>,0>
{
typedef Head Result;
};
template <class Head, class Tail, unsigned int i>
struct TypeAt<vector<Head, Tail>, i>
{
typedef typename TypeAt<Tail, i-1>::Result Result;
};

template <class TList, template<class> class Unit>
class GenScatterHierarchy;//主模板

template<class T1, class T2, template<class> class Unit>
class GenScatterHierarchy<vector<T1,T2> , Unit>//对主模进行特化。
: public GenScatterHierarchy<T1, Unit>
, public GenScatterHierarchy<T2, Unit>
{

};

template<class ATomicType, template<class> class Unit>
class GenScatterHierarchy : public Unit<ATomicType>
{

};

template<template<class> class Unit>
class GenScatterHierarchy<NullType, Unit>{

};



template<class TList, template<class> class Unit>
Unit<typename front<TList>::type >& FieldHelper(
GenScatterHierarchy<TList,Unit>& obj, Int2Type<0> )
{
GenScatterHierarchy<typename front<TList>::type, Unit>& leftBase = obj;
return leftBase;
};

template<int i, class TList, template<class> class Unit>
Unit< typename TypeAt<TList,i>::Result >& FieldHelper(
GenScatterHierarchy<TList, Unit>& obj, Int2Type<i>)
{
typename GenScatterHierarchy<typename at<TList,int_<1>>::type, Unit>& rightBase = obj;
return FieldHelper(rightBase, Int2Type<i-1>());
}

template <int i, class TList, template<class> class Unit>
Unit<typename TypeAt<TList,i>::Result >&
Field (GenScatterHierarchy<TList, Unit>& obj)
{
return FieldHelper(obj, Int2Type<i>() );
}


int _tmain(int argc, _TCHAR* argv[])
{

typedef GenScatterHierarchy<typename my_vector<int,float,string>::type, Holder> Info;
Info obj;
float b = (static_cast<Holder<float>&>(obj)).vaule;//ok
//deref<begin<vector<int>::type>::type>::type a=9;

int a = Field<0>(obj).vaule;
float fl = Field<1>(obj).vaule;
string str = Field<2>(obj).vaule;



return 0;

}
o0MyBelieve0o 2009-05-08
  • 打赏
  • 举报
回复
接分啊!!!!
huliang66 2009-05-08
  • 打赏
  • 举报
回复
接分
thinkboy234 2009-05-08
  • 打赏
  • 举报
回复
JF
plaindew 2009-05-08
  • 打赏
  • 举报
回复
帮顶
Sou2012 2009-05-08
  • 打赏
  • 举报
回复
恭喜了哦
piginthetree 2009-05-08
  • 打赏
  • 举报
回复
接分
o0MyBelieve0o 2009-05-08
  • 打赏
  • 举报
回复
deng2000 2009-05-08
  • 打赏
  • 举报
回复
[Quote=引用 101 楼 yshuise 的回复:]
谢谢,我在74楼已经解决了这个问题。但是,有个缺点就是不能有相同的类型,这样就有二义性。
[/Quote]
是的,74楼的程序能也能达到同样目的,且比我在97楼的做法简单很多, 不过其代价是,在实例化GenScatterHierarchy时需要嵌套vector:
typedef GenScatterHierarchy<vector<int, vector<string,NullType> >, Holder> Info;
而97楼的程序则可以在一个vector中顺序填入多个类别:
typedef GenScatterHierarchy<vector<int, string>, Holder> Info;
当vector中的类别比较多时,后者的优势比较明显.

74楼的程序只用到两个类参的vector,象front, pop_front这些体现vector威力的模板都没用到. 实际上,在74楼的程序中,完全可以自己声明一个简单的模板:
template<class T1, class T2>
class my_vector
{
};
用它来代替boost::mpl::vector, 而不使用MPL库的任何模板,这样的效果是一样的.

关于有相同类型时产生二义性的问题,可以用类似Loki中FieldHelper相似的方法解决.如下是一个例子程序,它创建的GenScatterHierarchy类参是vector<int, string, int>,其中有重复的int类.


#include "stdafx.h"
#include <iostream>
#include <string>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/erase.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/front.hpp>

using std::string;
using std::cout;
using std::endl;
using boost::mpl::at ;
using boost::mpl::int_;
using boost::mpl::pop_front;
using boost::mpl::vector;
using boost::mpl::deref;
using boost::mpl::begin;
using boost::mpl::front;

#include "boost/preprocessor/arithmetic/sub.hpp"
#include "boost/preprocessor/tuple/elem.hpp"
#include "boost/preprocessor/enum_params_with_a_default.hpp"
#include "boost/preprocessor/enum_params.hpp"
#include "boost/preprocessor/enum.hpp"
#include "boost/preprocessor/repeat.hpp"
#include "boost/preprocessor/comma_if.hpp"
#include "boost/preprocessor/iterate.hpp"
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/comparison/not_equal.hpp>
#include <boost/preprocessor/repetition/for.hpp>
#include <boost/preprocessor/tuple/elem.hpp>

#include "boost/config.hpp"


#define AUX_VECTOR_N_PARAMS(n, param) \
BOOST_PP_ENUM_PARAMS(n, param)

#define AUX_VECTOR_N_PARTIAL_SPEC_PARAMS(n, param, def) \
BOOST_PP_ENUM_PARAMS(n, param) \
BOOST_PP_COMMA_IF(n) \
BOOST_PP_ENUM( \
BOOST_PP_SUB_D(1,BOOST_MPL_LIMIT_VECTOR_SIZE,n) \
, BOOST_PP_TUPLE_ELEM_3_2 \
, def \
) \
/**/

using boost::mpl::void_;


/*
#define DEF_NUM(my_num) template<AUX_VECTOR_N_PARAMS(my_num,class T)> \
struct ToVector<boost::mpl::vector##my_num< AUX_VECTOR_N_PARAMS(my_num,T) > > \
{ \
typedef vector< AUX_VECTOR_N_PARTIAL_SPEC_PARAMS(my_num,T,void_)> type; \
};\
*/

#define DEF_NUM(my_num) template<AUX_VECTOR_N_PARAMS(my_num,class T)> \
struct ToVector< BOOST_PP_CAT(boost::mpl::vector, my_num< AUX_VECTOR_N_PARAMS(my_num,T)) > > \
{ \
typedef vector< AUX_VECTOR_N_PARTIAL_SPEC_PARAMS(my_num,T,void_)> type; \
};


template<class T>
struct ToVector;


#define PRED(r, state) \
BOOST_PP_NOT_EQUAL( \
BOOST_PP_TUPLE_ELEM(2, 0, state), \
BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(2, 1, state)) \
) \
/**/

#define OP(r, state) \
( \
BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(2, 0, state)), \
BOOST_PP_TUPLE_ELEM(2, 1, state) \
) \
/**/

#define MACRO(r, state) DEF_NUM(BOOST_PP_TUPLE_ELEM(2, 0, state))

#define BOOST_MPL_LIMIT_VECTOR_SIZE_1 BOOST_PP_DEC(BOOST_MPL_LIMIT_VECTOR_SIZE)

BOOST_PP_FOR((0, BOOST_MPL_LIMIT_VECTOR_SIZE_1), PRED, OP, MACRO)


// mytest
template <class TList, template<class> class Unit>
class GenScatterHierarchy;

template <AUX_VECTOR_N_PARAMS(BOOST_MPL_LIMIT_VECTOR_SIZE, class T), template<class> class Unit>
class GenScatterHierarchy<vector<AUX_VECTOR_N_PARAMS(BOOST_MPL_LIMIT_VECTOR_SIZE, T)>, Unit>
: public GenScatterHierarchy<typename front<vector<AUX_VECTOR_N_PARAMS(BOOST_MPL_LIMIT_VECTOR_SIZE, T)> >::type, Unit>,
public GenScatterHierarchy<typename ToVector<typename pop_front<vector<AUX_VECTOR_N_PARAMS(BOOST_MPL_LIMIT_VECTOR_SIZE, T)> >::type >::type, Unit>
{
public:
typedef GenScatterHierarchy<typename front<vector<AUX_VECTOR_N_PARAMS(BOOST_MPL_LIMIT_VECTOR_SIZE, T)> >::type, Unit> LeftType;
typedef GenScatterHierarchy<typename ToVector<typename pop_front<vector<AUX_VECTOR_N_PARAMS(BOOST_MPL_LIMIT_VECTOR_SIZE, T)> >::type >::type, Unit> RightType;

typedef typename front<vector<AUX_VECTOR_N_PARAMS(BOOST_MPL_LIMIT_VECTOR_SIZE, T)> >::type FirstElemType;
typedef Unit<FirstElemType> FirstType;
};

template<template<class> class Unit>
class GenScatterHierarchy<vector<AUX_VECTOR_N_PARTIAL_SPEC_PARAMS(0,T,void_)>, Unit>
{
};

template<class ATomicType, template<class> class Unit>
class GenScatterHierarchy : public Unit<ATomicType>
{
typedef Unit<ATomicType> LeftBase;
};


template <class T>
struct Holder{
T value;
};

template <class H, unsigned int i> struct FieldHelper;

template <class H>
struct FieldHelper<H, 0>
{
typedef typename H::LeftType LeftType;
typedef typename H::RightType RightType;
typedef typename H::FirstType ResultType;

static ResultType& Do(H& obj)
{
LeftType& left = obj;
return left;
}
};

template <class H, unsigned int i>
struct FieldHelper
{
typedef typename H::LeftType LeftType;
typedef typename H::RightType RightType;
typedef typename FieldHelper<RightType, i-1>::ResultType ResultType;

static ResultType& Do(H& obj)
{
RightType& right = obj;
return FieldHelper<RightType, i - 1>::Do(right);
}
};

int _tmain(int argc, _TCHAR* argv[])
{
typedef GenScatterHierarchy<vector<int, string, int>, Holder> H;

H obj;

Holder<int>& numHolder1 = FieldHelper<H,0>::Do(obj);
Holder<string>& strHolder = FieldHelper<H,1>::Do(obj);
Holder<int>& numHolder2 = FieldHelper<H,2>::Do(obj);

numHolder1.value = 5;
numHolder2.value = 6;
strHolder.value = "Test";

cout << FieldHelper<H,0>::Do(obj).value << " " << FieldHelper<H,1>::Do(obj).value << " " << FieldHelper<H,2>::Do(obj).value << endl;

return 0;

}


程序编译运行后,结果为

5 Test 6
  • 打赏
  • 举报
回复
shen me a
lg2lg 2009-05-08
  • 打赏
  • 举报
回复
赞一个
fuzzy_man 2009-05-08
  • 打赏
  • 举报
回复
jf
十八道胡同 2009-05-08
  • 打赏
  • 举报
回复
帮顶~
madelaop5566 2009-05-08
  • 打赏
  • 举报
回复
c++滴不会
really3353 2009-05-08
  • 打赏
  • 举报
回复
接分,呵呵
加载更多回复(106)

64,640

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧