DraculaW

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  19 随笔 :: 0 文章 :: 7 评论 :: 0 Trackbacks
模板的引入 使c++产生了泛型的算法 泛型的容器
这两个是个好东西 但是在将两项技术结合的时候产生了一个问题 就是在写程序的时候要暴露对象的类型
就像这个样子 :
template<typename T>
vector<T>::iterator find(const T& )
{
........
}
而如果暴露了类型的话 那么就不能写一段代码而完成问题了 必须为每种容器都写出相同的算法
怎么办呢 可以在find中传出两个参数
template<typename T>
vector<T>::iterator find(const T&, T& result )
{
........
}
但是好像还是有问题 譬如类型的引用 还有size 指针 等等 都是不同的类型 写起来还是很头大
于是 聪明的人们想出了type traits这项技术
这项技术
typename<typename T>
class iterator
{
public:
    typedef T value_type
}
typename<typename I>
typename I::value_type
find(I &)
{
}

与STL的实现不同 在boost中 他们使用的是模板片特化来实现的type traits
基本思想就是 默认大部分都不支持某种特性 然后 当某个类型支持时就为他特化一个类 支持这样的特性
感觉这样写的话 在特化的时候会不会代码会比较多呢 ...
具体就是
template<typename T>
class something
{
// 在这里写对广大的类的操作
}

然后对于特殊的类型 譬如说 int
template<>
class something<int>
{
//然后在这里写对Int做的特殊的操作
}

而为了type traits来说 它的特殊操作就是在泛型类里面做一个枚举 值为false而在 int里面这个值为true
那么 当算法来用这个对象时 可以根据这个枚举的值来选择相应的算法 ,譬如对int的速度比较快的 或者对泛型的正确的算法

下面是 std::swap的一个优化版本

//
// iter_swap:
// tests whether iterator is a proxying iterator or not, and
// uses optimal form accordingly:
//
namespace detail{
template <typename I>
static void do_swap(I one, I two, const boost::false_type&)
{
    typedef typename std::iterator_traits<I>::value_type v_t;
    v_t v = *one;
    *one = *two;
    *two = v;
}
template <typename I>
static void do_swap(I one, I two, const boost::true_type&)
{
    using std::swap;
    swap(*one, *two);
}
}

template <typename I1, typename I2>
inline void iter_swap(I1 one, I2 two)
{
    //
    // See is both arguments are non-proxying iterators,
    // and if both iterator the same type:
    //
    typedef typename std::iterator_traits<I1>::reference r1_t;
    typedef typename std::iterator_traits<I2>::reference r2_t;
    typedef boost::integral_constant<bool,
    ::boost::is_reference<r1_t>::value
        && ::boost::is_reference<r2_t>::value
        && ::boost::is_same<r1_t, r2_t>::value> truth_type;

    detail::do_swap(one, two, truth_type());
}

其中 boost::integral_constant<bool, ::boost::is_reference<r1_t>::value
        && ::boost::is_reference<r2_t>::value
        && ::boost::is_same<r1_t, r2_t>::value> truth_type
就是一个枚举 看传入的参数是否可以用std::swap 如果可以则连接到std::swap不然就用自己写的 呵呵
posted on 2007-11-15 20:43 DraculaW 阅读(923) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理