分享
 
 
 

Boost如何”拧“VC6以实现mem_fun可以接收返回值为void的函数

王朝vc·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

Boost如何”拧“VC6以实现mem_fun可以接收返回值为void的成员函数

VC6自带的STL,mem_fun可以接收的成员函数返回值不能为void。

在<functional>文件中可以看到具体的实现代码为:

template<class _Return, class _Type>

class mem_fun_t

{

public:

//construction...

_Return operator()(_Type *_P) const

{return ((_P->*_FuncPtr)()); }

private:

//member function pointer ...

};

当_Return为void时,VC6会报一个编译错误:void' function returning a value。

有心想解决一下。首先,尝试使用static_cast。

_Return operator()(_Type *_P) const

{return static_cast<void)((_P->*_FuncPtr)()); }

发现报同样错误,看来VC6确实对标准支持一般。

然后当然想采用特化,对返回值类型进行void特化,但是VC6根本不支持部分特化,例如:

template<class _Type>

class mem_fun_t<void, _Type>

{..

};

报编译错误,重复的模板定义。 template class has already been defined as a non-template class

幸亏VC仍然支持完全特化,于是采用“增加一层“定律,由于只有返回值为void的时侯需要特别处理,

因此定义一个通用模板,然后对void进行完全特化:

template <class Return> struct return_trait

{

...

};

template<> struct return_trait<void>

{

...

};

下面的代码就是根据boost实现来的,简化了很多。毕竟阅读困难。

在这两者之间就可以对返回类型为void的情况进行特别处理了:

通用模板定义如下:

template <class Return> struct return_trait

{

template<class Return, class Type, class F>

struct inner_mem_fun_type

{

F func_;

inner_mem_fun_type(F f) : func_(f) {}

Return operator()(Type * type)

{

return (type->*func_)();

}

};

void的完全特化模板和上面一模一样,只是将

return (type->*func_)();

中的return去掉即可,就不多写了。其中boost使用了宏和#include来实现这个功能。

然后定义一个模板函数,用来自动实例化合适的模板类型;

template<class Return, class Type>

return_trait<Return>::inner_mem_fun_type<Return, Type, Return (Type::*)()>

mem_func(Return (Type::*f)())

{

return return_trait<Return>::inner_mem_fun_type<Return, Type, Return (Type::*)()>(f);

}

boost其实在mem_fn中又创建了一个间接层次,我发现上面直接返回内嵌类VC6也可以编译。可能是因为其他的编译器需要这样处理。其中inner_mem_fun_type接收3个参数,第3个参数为成员函数指针类型,完全可以由Return,Type确定,但是发现如果不加上这个,VC6出现internal compiler error。我在这上面就折腾了很久。也不知道boost是如何发现这个解决方法的。

举一反三,对于类似的部分特化的需求,在VC6下都应该可以使用该方法解决。

例如,一个模板类有2个类型参数T1, T2,其中需要对int, T2进行部分特化处理。

最标准的当然是

template<class Type1, class Type2> struct Foo

{

...

};

对int, Type2部分特化

template<class Type2> struct<int, Type2>Foo

{

...

};

前面说了VC6不支持这种部分特化,因此可以如下;

提出Type1,定义一个嵌套结构:

template<class Type1> struct type_traits

{

template<class Type1, class Type2> struct Foo

{

};

};

对Type1为int进行完全特化:

template<> struct type_traits<int>

{

template<class Type1, class Type2> struct Foo

{

};

};

使用之:

type_traits<double>::Foo<double, double> f1;

type_traits<int>::Foo<int, double> f2;

很好。但是毕竟毕竟繁琐,当然想搞个模板成员函数推演出来:

template<class Type1, class Type2>

type_traits<Type1>::Foo<Type1, Type2> make_foo(Type1 t1, Type2 t2)

{

return type_traits<Type1>::Foo<Type1, Type2>(t1, t2);

}

结果到这一步又是internal compiler error。

看来还又得学习boost中的,使用继承关系。再来:

定义一个Wapper class,从嵌套类type_traits::Foo派生

template<class Type1, class Type2>

struct FooWapper : public type_traits<Type1>::Foo<Type1, Type2>

{

FooWapper(Type1 t1, Type2 t2) : type_traits<Type1>::Foo<Type1, Type2>(t1, t2) {}

};

maker函数返回FooWapper模板类,而不是嵌套的模板类

template<class Type1, class Type2>

FooWapper<Type1, Type2> make_foo(Type1 t1, Type2 t2)

{

return FooWapper<Type1, Type2>(t1, t2);

}

再试:

make_foo(1, 2.0);

make_foo('a', 2.0);

编译成功。测试也对。通过这种手法,应该可以在VC6下解决一部分部分特化的问题,如果需要特化的类型以定的话。但是想对例如T*这种进行指针特化估计是没有希望了。不错。boost!

完整的源程序:

//通用Type1, Type2

template<class Type1> struct type_traits

{

template<class Type1, class Type2> struct Foo

{

Foo(Type1 t1, Type2 t2)

{

std::cout << "noint+type1" << std::endl;

}

};

};

//特化的int,Type2

template<> struct type_traits<int>

{

template<class Type1, class Type2> struct Foo

{

Foo(Type1 t1, Type2 t2)

{

std::cout << "int+type2" << std::endl;

}

};

};

//Wrapper 类

template<class Type1, class Type2>

struct FooWapper : public type_traits<Type1>::Foo<Type1, Type2>

{

FooWapper(Type1 t1, Type2 t2) : type_traits<Type1>::Foo<Type1, Type2>(t1, t2) {}

};

//maker函数用于推演

template<class Type1, class Type2>

FooWapper<Type1, Type2> inline make_foo(Type1 t1, Type2 t2)

{

return FooWapper<Type1, Type2>(t1, t2);

}

//测试程序

int main()

{

make_foo(1, 2.0); //调用特化的<int, type2>

make_foo('a', 2.0); //调用通用的<type1, type2>

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有