本文主要是介绍萃取和constexpr,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
最近重温了一下萃取发现其与constexpr有相似之处,记录如下。
一、引出萃取
STL的在中心思想是将容器和算法分开,再通过迭代器iterator这一迭代器来将两者粘合起来。
通过迭代器进行算法计算,需要涉及两个问题:
问题一.通常需要针对不同类型的迭代器进行不同的算法操作。需要在编译时期获取迭代器的类型信息。
以advance为例,对于random_access_iterator可以在O(1)的时间复杂度完成,但是对于bidirectional_iterator需要在O(n)的时间复杂度完成。
问题二.通常需要运用迭代器的相应型别,相应型别之一就是iterator所指向数据的类型。
C++支持sizeof(),但是不支持typeof()。即使通过RTTI的typeid()获取到类型名称,也不能进行变量声明使用。
解决办法:通过function template的函数推导可以获取到iterator所指向数据的类型。
template<typename Iter, typename T>
void func_impl(Iter iter, T t)
{T tmp;//这里解决了迭代器所指类型的型别问题...//函数实现
};
template<typename Iter>
void func(Iter iter)
{func_impl(iter, *iter);
};
int main
{vector<int> tmp_v = {1,2,3};func(tmp_v.begin());
}
迭代器常用的型别有五种,并不是每一种都可以通过template的参数推导机制获取,我们需要更全面的解法,即traits。
这五种型别是:
- value_type
- difference_type
- reference_type
- pointer_type
- iterator_category
Traits不是一种C++关键字或一个预定义的构件。
是一种技术,也是C++程序员需要共同遵守的协议。这个技术的要求之一是,它对内置类型或用户自定义类型的表现必须一样好。
“traits必须能够实施与内置类型”意味着“类型内的嵌套信息”这种东西就出局了,因为我们无法将信息嵌套在原始指针内。因此,类型的traits信息必须位于类型自身之外。
标准技术是把它放入一个template及其一个或多个特化版本中。这样的templates在标准程序库中有若干个,其中针对迭代器的被命名为iterator_traits。
template<typename T>//template用来处理迭代器型别的信息
struct iterator_traits;
问题一的答案是引入iterator_category;问题二答案是引入value_type。
二、iterator_category和value_type
iterator_category
iterator_traits的运作方式是针对每一个类型的IterT在struct iterator_traits<IterT>中使用typedef声明一个iterator_category。
这个typedef用来确认IterT的迭代器分类。
iterator_traits以两部分实现上述所言:
第一部分:
首先它要求每一个用户自定义的迭代器类型必须嵌套一个typedef,名为iterator_category,用来确认适当的卷标结构。
例如,deque的迭代器支持随机访问,所以 针对一个deque迭代器的设计如下
template<...>//略写tempalte参数
class deque
{
public:class iterator {public:typedef random_access_iterator_tag iterator_category;};
};
list的iterator可以双向前进
template<...>//略写tempalte参数
class list
{
public:class iterator {public:typedef bidirectional_iterator_tag iterator_category;};
};
至于iterator_traits只是类似地响应iterator class的嵌套式 typedef:
template<typename IterT>
class iterator_traits {typedef typename IterT::iterator_category iterator_category;...
};
第二部分:
第二部分专门用来应对指针。
上述方法对用户自定义的Iter类型行得通,但是不适用于指针类型,因为指针不可能嵌套typedef。
因为支持指针迭代器,iterator_traits还特别对指针类型提供了一个偏特化版本。由于指针的行径与random_access迭代器类似,所以iterator_traits为指针指定的迭代器类型是:
template<typename IterT>
struct iterator_traits<IterT*>
{typedef random_access_iterator_tag iterator_category;...
};
三、constexpr与萃取相关联
---------------------------------有待续写---------------------------------------------------
这篇关于萃取和constexpr的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!