c++中的概念模型

xiaoxiao2021-02-28  104

double sum(double array[], int n) { double result = 0; for (int i = 0; i < n; ++i) result = result + array[i]; return result; }

 这是一个简单的求加的函数。

 

 

template<typename T> T sum(T array[], int n) { T result = 0; for (int i = 0; i < n; ++i) result = result + array[i]; return result; }

 

第一步,是模板化。

 

struct pod { int i; }; int main() { pod values[3] = { {1}, {2}, {3} }; sum(values, 3); return 0; }

 

第二步是测试。。。

 

 

 这个会出问题么?当然会咯。。所以说。。。我们需要引入概念模型。。

 

 

 所谓的概念模型就是类型检查。。,当引入某个模板的时候,检查它的参数符合不符合一组接口。。。。。。

 

 

 

#include <boost/concept_check.hpp> template <class RandomAccessIter> void stable_sort(RandomAccessIter first, RandomAccessIter last) { function_requires< RandomAccessIteratorConcept<RandomAccessIter> >(); //... bla bla bla...... }

 

 

上面的代码,在说。。如果我们的 first和last 不符合 function_requires函数。。就会报错。

 

 

 

template <class Concept> inline void function_requires(mpl::identity<Concept>* = 0) { #if !defined(NDEBUG) void (Concept::*x)() = BOOST_FPTR Concept::constraints; ignore_unused_variable_warning(x); #endif }

 

这个代码解释了上面的function_requires的样子。注意其中的 inline 和 !  if !defined(NDEBUG)。

 

而且,其中的void(Concept::*x)()是一个在类Concept内的指针类型,指向了Concept中的constriants;

 

这就是它的巧妙之处,我们仅仅去取一个函数的地址。而这个函数的参数类型在以下地方给出。

 

 

template <class TT> struct RandomAccessIteratorConcept { void constraints() { function_requires< BidirectionalIteratorConcept<TT> >(); function_requires< ComparableConcept<TT> >(); #ifndef BOOST_NO_STD_ITERATOR_TRAITS typedef typename std::iterator_traits<TT>::iterator_category C; function_requires< ConvertibleConcept< C, std::random_access_iterator_tag> >(); typedef typename std::iterator_traits<TT>::reference R; #endif i += n; // require assignment addition operator i = i + n; i = n + i; // require addition with difference type i -= n; // require assignment subtraction operator i = i - n; // require subtraction with difference type n = i - j; // require difference operator (void)i[n]; // require element access operator } TT a, b; TT i, j; #ifndef BOOST_NO_STD_ITERATOR_TRAITS typename std::iterator_traits<TT>::difference_type n; #else std::ptrdiff_t n; #endif };

 

 

至此,结束。

 

疑点有很多:

1.为什么要这样做?

 

  答案:因为原来的出错信息很模糊。。现在可以准确定位。。。

 

2.不执行函数就能确定函数的执行过程?

 

3.关于如何check.;;据说是利用虚函数机制,进行check?constraints是个虚函数???

 

 

 

 

 

 

 

 

转载请注明原文地址: https://www.6miu.com/read-74382.html

最新回复(0)