您的位置:首页 > 大数据 > 人工智能

[function & type_traits] VC6 的 function traits 和 function 模板的新的实现方法

2008-04-05 16:17 453 查看
以前写的《用 C++ 实现 C# 中的 委托/事件》在VC6中无法完美实现 现在终于可以了(还有一点点小缺憾)
委托部分就不提了

首先说function traits
在最新的boost 1.35中
VC6的function traits只支持参数个数
如:
 typedef int func(int);
 assert(boost::function_traits<func>::arity == 1);
不能得到参数和返回值的类型
用下面的方法, 就可以突破这个局限了

#include <boost/typeof/typeof.hpp>
namespace boost {
namespace detail {
template<typename Function> struct function_traits_helper;

template<typename R>
struct function_traits_helper0
{
  BOOST_STATIC_CONSTANT(unsigned, arity = 0);
  typedef R result_type;
};

template<typename R, typename T1>
struct function_traits_helper1
{
  BOOST_STATIC_CONSTANT(unsigned, arity = 1);
  typedef R result_type;
  typedef T1 arg1_type;
.
.
.
};

template<typename F>
function_traits_helper<F> function_arity_helper(F* f);

template<typename R>
function_traits_helper0<R> function_arity_helper(R (*f)());

template<typename R, typename T1>
function_traits_helper1<R, T1> function_arity_helper(R (*f)(T1));
.
.
.
} // end namespace detail

template<typename Function>
struct function_traits : public
BOOST_TYPEOF(detail::function_arity_helper((Function*)0))
{
};
} // end namespace boost

限制:
VC6 不支持下面的语法:
 typedef boost::function_traits<int(int)> function_traits1;
 typedef boost::function_traits<int(*)(int)> function_traits2;
 typedef boost::function_traits<int(&)(int)> function_traits3;
只支持:
 typedef int func(int);
 typedef boost::function_traits<func> function_traits1;

////////////////////////////////////////

然后就轮到function模板了
boost中VC6的function模板只支持
如:
 int func0();
 boost::funtion0<int> fun0 = func0;
 int func1(int);
 boost::funtion1<int, int> fun1 = func1;
用起来甚是不爽
用了新方法之后就可以:
 int func0();
 typedef int typefunc0();
 boost::funtion<typefunc0> fun0 = func0;
 int func1(int);
 typedef int typefunc1();
 boost::funtion<typefunc1> fun1 = func1;
总算是改进了些

#include <boost/typeof/typeof.hpp>
#include <boost/function.hpp>
namespace boost
{
namespace function_detail {
template<typename F>
function_base function_arity_helper(F* f);

template<typename R>
function0<R> function_arity_helper(R (*f)());

template<typename R, typename T1>
function1<R, T1> function_arity_helper(R (*f)(T1));
.
.
.
} // end namespace detail

template<typename Function, typename Allocator = std::allocator<void> >
struct function : public
BOOST_TYPEOF(function_detail::function_arity_helper((Function*)0))
{
  typedef
BOOST_TYPEOF_TPL(function_detail::function_arity_helper((Function*)0))
base_type;
  typedef function self_type;

  struct clear_type {};

public:
  //typedef typename base_type::allocator_type allocator_type;
  typedef Allocator allocator_type;

  function() : base_type() {}

  template<typename Functor>
  function(Functor f
#ifndef BOOST_NO_SFINAE
           ,typename enable_if_c<
                            (boost::type_traits::ice_not<
                          (is_integral<Functor>::value)>::value),
                       int>::type = 0
#endif
           ) :
    base_type(f)
  {
  }

#ifndef BOOST_NO_SFINAE
  function(clear_type*) : base_type() {}
#endif

  function(const self_type& f) : base_type(static_cast<const
base_type&>(f)){}

  function(const base_type& f) : base_type(static_cast<const
base_type&>(f)){}

  self_type& operator=(const self_type& f)
  {
    self_type(f).swap(*this);
    return *this;
  }

  template<typename Functor>
#ifndef BOOST_NO_SFINAE
  typename enable_if_c<
                            (boost::type_traits::ice_not<
                         (is_integral<Functor>::value)>::value),
                      self_type&>::type
#else
  self_type&
#endif
  operator=(Functor f)
  {
    self_type(f).swap(*this);
    return *this;
  }

#ifndef BOOST_NO_SFINAE
  self_type& operator=(clear_type*)
  {
    this->clear();
    return *this;
  }
#endif

  self_type& operator=(const base_type& f)
  {
    self_type(f).swap(*this);
    return *this;
  }
};

template<typename Signature, typename Allocator>
inline void swap(function<Signature, Allocator>& f1,
                 function<Signature, Allocator>& f2)
{
  f1.swap(f2);
}
}

限制:
同function traits.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐