十分钟让你对C++ Traits大彻大悟
来源:互联网 发布:mac os 10.11和10.13 编辑:程序博客网 时间:2024/05/17 06:24
转自:http://www.cnblogs.com/pugang/archive/2012/10/17/2727378.html
最近和一个朋友闲聊的时候他对我说一个人对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; };
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;
}
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);
}
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
- 十分钟让你对C++ Traits大彻大悟
- 十分钟让你明白Objective-C的语法
- 十分钟让你懂得基金是什么
- 十分钟让你懂得基金是什么
- 十分钟让你懂得中国经济(转载)
- 十分钟让你看懂中国经济形势
- 十分钟让你看懂中国经济形势
- 十分钟让你看懂中国经济形势
- 十分钟让你看懂中国经济形势
- 十分钟让你看懂中国经济形势!
- 十分钟让你学会放松
- 十分钟让你读懂中国经济
- 十分钟让你明白Objective-C的语法(和Java、C++的对比)
- 十分钟让你明白Objective-C的语法(和Java、C++的对比)
- 十分钟让你明白Objective-C的语法(和Java、C++的对比)
- 十分钟让你明白Objective-C的语法(和Java、C++的对比)
- 十分钟让你明白Objective-C的语法(和Java、C++的对比)
- 十分钟让你明白Objective-C的语法(和Java、C++的对比)
- 李长春离京出访南亚三国-李长春-出访-南亚三国
- C++、Java和C#语言在处理“虚拟私有方法”上的差异
- Camera相关文章
- 一段ARM代码样例
- 类型转换运算符
- 十分钟让你对C++ Traits大彻大悟
- Qt:截取当前窗口图
- ExtJs有个Window,然后有个属性html(iframe),到另外一个页面,然后在另外页面关闭,同时关闭window
- VIM 选择模式 的用法
- 和机器学习和计算机视觉相关的数学
- 抽象类与接口的区别
- 用Java或Jsp向数据库存取二进制图片
- Bees can bite as well as sting
- 21个免费的UI界面设计工具、资源及网站