博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
十分钟让你对C++ Traits大彻大悟
阅读量:7113 次
发布时间:2019-06-28

本文共 2026 字,大约阅读时间需要 6 分钟。

最近和一个朋友闲聊的时候他对我说一个人对C++的理解很多种境界,朋友不是个喜欢吹牛的人,于是听他细说,觉得很是有道理。

想写一篇C++ traits方面的文章已经有一段时间了,但是说实话traits这项技术确实有些晦涩,很担心写完了达不到期望的效果,于是每每试图以简炼的文字表达,慢慢的就等到了今天。

先说说我为什么专门对这项技术写一篇文章吧。记得当时在看STL/boost代码的时候经常遇到traits,当时惊叹于代码原来可以这样写,但是最初根本是看不懂的,查了一些资料才彻底理解了traits存在的意义。

本质定义:加上一层间接性,换来以定的灵活性。

看下面的代码:

template <typename T> 
struct is_void
static 
const 
bool value = 
false; };
template <> 
struct is_void<
void>
static 
const 
bool value = 
true; };

 

我们可以这样使用这份代码:

Is_void<false>::value 调用第一份代码,也就是说只要我们传入一个参数像下面这样:

Is_void<T>::value,其中T可以为任意类型,我们就可以判断这个类型是不是void在编译期。

完整测试代码如下:

template <typename T> 
struct is_void
    
static 
const 
bool value = 
false
};
template <> 
struct is_void<
void>
    
static 
const 
bool value = 
true
};
int _tmain(
int argc, _TCHAR* argv[])
{
    std::cout<<is_void<
int>::value;
    
    std::cout<<is_void<
void>::value;
    
return 
0;
}

 

下面我们来看一个复杂点的例子,考验一下你的理解:

namespace detail{
    template <
bool b>
    
struct copier
    {
       template<typename I1, typename I2>
       
static I2 do_copy(I1 first, I1 last, I2 
out);
    };
    template <
bool b>
    template<typename I1, typename I2>
    I2 copier<b>::do_copy(I1 first, I1 last, I2 
out)
    {
       
while(first != last)
       {
          *
out = *first;
          ++
out;
          ++first;
       }
       
return 
out;
    }
    template <>
    
struct copier<
true>
    {
       template<typename I1, typename I2>
       
static I2* do_copy(I1* first, I1* last, I2* 
out)
       {
          memcpy(
out, first, (last-first)*
sizeof(I2));
          
return 
out+(last-first);
       }
    };
    }
    template<typename I1, typename I2>
    inline I2 copy(I1 first, I1 last, I2 
out)
    {
       typedef typename 
        boost::remove_cv<
         typename std::iterator_traits<I1>
          ::value_type>::type v1_t;
       typedef typename 
        boost::remove_cv<
         typename std::iterator_traits<I2>
          ::value_type>::type v2_t;
       
enum{ can_opt = 
          boost::is_same<v1_t, v2_t>::value
          && boost::is_pointer<I1>::value
          && boost::is_pointer<I2>::value
          && boost::
          has_trivial_assign<v1_t>::value 
       };
       
return detail::copier<can_opt>::
          do_copy(first, last, 
out);
}

 

总结

本文试图以最简洁的方式阐述对C++ traits 的理解,当你理解了第二个例子的时候,相信你已经理解了C++ traits,恭喜你对C++ 的理解上了一个层次。

 

Bibliography:

http://www.boost.org/doc/libs/1_31_0/libs/type_traits/c++_type_traits.htm

 

转载地址:http://dkghl.baihongyu.com/

你可能感兴趣的文章
别说无所谓
查看>>
irb的子会话 - 相思雨 - 博客园
查看>>
python 网络编程
查看>>
aspx 页面数据绑定 前台数据绑定
查看>>
《推荐系统实践》样章:如何利用用户标签数据
查看>>
U-Boot Makefile文件分析
查看>>
Puppetmaster高可用和可扩展的方案设计
查看>>
[2013EJDE]Osgood type regularity criterion for the $3$D Newton-Boussinesq equations
查看>>
黄疸案
查看>>
[转载]ASP.NET伪静态页面的实现和伪静态在IIS7.0中的配置
查看>>
【转】Android源代码编译命令m/mm/mmm/make分析--不错
查看>>
【SQL】SQL中笛卡尔积、内连接、外连接的数据演示
查看>>
HTTP解析
查看>>
MemCache超详细解读
查看>>
python numpy 教程
查看>>
手机web如何实现多平台分享
查看>>
策略模式和观察者模式
查看>>
详解CALayer 和 UIView的区别和联系
查看>>
eclipse中报错:java.lang.OutOfMemoryError: Java heap space
查看>>
Ubuntu 16.04 grub rescue 模式下修复 grub
查看>>