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

本文介绍如何在Visual C++ 6.0环境中利用Boost库的改进版本实现更灵活的函数特性和函数模板操作,包括自定义函数特性的实现方法及优化后的函数模板使用方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以前写的《用 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.

&lt;think&gt;好的,我需要介绍一下C++中的&lt;type_traits&gt;头文件。首先,用户可能想知道这个头文件的基本用途,也就是类型特性检查。我应该从模板元编程的角度入手,说明它在编译时类型检查操作中的作用。 接下来,要分点介绍主要内容。可能需要分为类型分类、类型关系、类型转换辅助类几个部分。每个部分需要举例子,比如is_integral、is_class这些类型分类的traits,还有is_base_of、is_convertible这样的类型关系检查。类型转换方面,remove_reference、add_const这些是常用的,得提到。辅助类如integral_constant可能也需要解释,因为它是很多traits的基础。 然后,需要说明使用场景,比如在模板中根据类型选择不同实现,或者优化代码。这里可以举一个例子,比如用enable_if来条件编译,或者用is_integral做静态断言,确保传入的是整数类型。 还要注意用户可能不太熟悉模板元编程,所以例子要简单明了,比如展示一个使用is_pointer的例子,或者如何用remove_pointer去掉指针修饰符。 另外,要提醒用户这些都是在编译时进行的,不会影响运行时性能,这也是type_traits的一个优势。 可能还需要提到C++11引入这个头文件,后续版本有增加内容,但基础功能在C++11就有了。这样用户知道需要支持C++11及以上。 最后,总结一下type_traits的重要性,强调它在编写泛型、高效且安全的代码中的作用,比如在标准库或模板库中的广泛应用。&lt;/think&gt;$\texttt{&lt;type\_traits&gt;}$ 是 C++ 标准库中用于 **编译时类型检查与操作** 的头文件,属于模板元编程的核心工具。以下是逐步解析: --- ### 一、核心功能 通过模板特化与编译器推导,实现: 1. **类型特性检查** $\text{例如:判断类型是否为整数、指针、类类型等}$ 2. **类型关系判断** $\text{例如:判断两个类型是否有继承关系}$ 3. **类型转换操作** $\text{例如:移除引用/const修饰、添加指针修饰等}$ --- ### 二、主要组成部分 #### 1. 类型分类 (Type Classification) | 特性模板 | 作用 | |-------------------------|-------------------------------| | $\texttt{is\_integral&lt;T&gt;}$ | 判断 T 是否为整型 | | $\texttt{is\_pointer&lt;T&gt;}$ | 判断 T 是否为指针 | | $\texttt{is\_class&lt;T&gt;}$ | 判断 T 是否为类或结构体 | ```cpp static_assert(std::is_integral&lt;int&gt;::value, &quot;int 是整型&quot;); // 通过 static_assert(std::is_pointer&lt;int*&gt;::value, &quot;int* 是指针&quot;); // 通过 ``` #### 2. 类型关系 (Type Relationships) | 特性模板 | 作用 | |--------------------------|-------------------------------| | $\texttt{is\_base\_of&lt;Base,Derived&gt;}$ | 判断 Base 是否是 Derived 的基类 | | $\texttt{is\_convertible&lt;From,To&gt;}$ | 判断 From 是否能隐式转换为 To | ```cpp class Base {}; class Derived : public Base {}; static_assert(std::is_base_of&lt;Base, Derived&gt;::value, &quot;继承关系成立&quot;); ``` #### 3. 类型转换 (Type Transformations) | 特性模板 | 作用 | |--------------------------|-------------------------------| | $\texttt{remove\_reference&lt;T&gt;}$ | 移除 T 的引用修饰 (如 int&amp; &rarr; int) | | $\texttt{add\_const&lt;T&gt;}$ | 为 T 添加 const 修饰 | ```cpp using NoRef = std::remove_reference&lt;int&amp;&gt;::type; // NoRef 是 int using ConstInt = std::add_const&lt;int&gt;::type; // ConstInt 是 const int ``` #### 4. 辅助工具 (Utilities) - $\texttt{integral\_constant}$: 将值包装为类型 $\text{($\texttt{true\_type}$ $\texttt{false\_type}$ 的基类)}$ - $\texttt{enable\_if}$: 条件性启用函数重载或模板特化 ```cpp template&lt;typename T&gt; typename std::enable_if&lt;std::is_integral&lt;T&gt;::value, T&gt;::type foo(T x) { return x * 2; } // 仅对整型类型启用此函数 ``` --- ### 三、典型应用场景 1. **模板条件编译** $\text{通过 $\texttt{enable\_if}$ 或 $\texttt{if\_constexpr}$ 实现分支选择}$ 2. **代码优化** $\text{针对不同类型生成特化代码(如 SIMD 指令优化)}$ 3. **类型安全检查** $\text{使用 $\texttt{static\_assert}$ 防止非法类型传入}$ --- ### 四、示例:实现泛型类型打印 ```cpp template&lt;typename T&gt; void print_type() { if constexpr (std::is_pointer_v&lt;T&gt;) { std::cout &lt;&lt; &quot;指针类型\n&quot;; } else if constexpr (std::is_integral_v&lt;T&gt;) { std::cout &lt;&lt; &quot;整型\n&quot;; } else { std::cout &lt;&lt; &quot;其他类型\n&quot;; } } ``` --- ### 五、注意事项 - **编译时行为**:所有检查在编译期完成,无运行时开销 - **C++11 起支持**:需编译器支持 C++11 或更高标准 - **结合 SFINAE 使用**:广泛用于模板元编程中的类型推导 通过灵活使用 $\texttt{&lt;type\_traits&gt;}$,可以显著增强代码的泛用性安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值