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>

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
© 2005- 王朝网络 版权所有