6

我想在一个地方知道这三个概念的精确而简洁的定义。答案的质量应该取决于以下两点。

  1. 展示一个简单的代码片段来展示概念/技术的用途和用途。
  2. 要简单易懂,以便没有任何接触过该领域的程序员可以掌握它。

笔记:

可能有很多正确的答案,因为每个概念都有许多不同的方面。如果有很多好的答案,我最终会将问题变成 CW 并汇总答案。

-- 接受后编辑 --

Boost 有一篇关于泛型编程概念的好文章

4

3 回答 3

8

概念是对类型的一组要求。例如,您可以有一个名为“RandomAccessible”的概念,它将要求置于它operator[](int)在 O(1) 时间内实现的类型上。

由于概念已从即将到来的 C++ 标准中删除,它们仅作为文档无形地存在于 C++ 中。例如,您可以阅读SGI 对 Container 概念的描述

当一个类型满足一个概念的所有要求时,你就称它为该概念的模型。例如,std::vector是 Container 概念的模型(或等价的std::vector“模型”Container)。

最后,策略是一个行为单元,它可以与其他行为单元组合以构建复杂的类。例如,假设您想构建两个类:一个固定大小的数组和一个动态调整大小的数组。这两个类有很多共享的功能,但是它们的存储机制和它们的一些功能不同(例如你不能调用push_back一个固定大小的数组)。

template <class T, class StoragePolicy>
class array : public StoragePolicy
{
public:
  T& operator[](int i) { return data[i]; }
};

template <class T, int N>
class fixed_storage
{
  T data[N];
};

template <class T>
class dynamic_storage
{
  T* data;

public:
  void push_back(const T& value) 
  {
    // Code for dynamic array insertion
  }
};

用法如下:

int main()
{
  array<int, fixed_storage<int, 10> > fixed_array;
  array<int, dynamic_storage<int> > dynamic_array;

  dynamic_array.push_back(1);
  fixed_array[9] = dynamic_array[0];
}

显然这是一个非常粗略和不完整的例子,但我希望它能够阐明政策背后的概念。

请注意,在示例中,我们可以说fixed_storagedynamic_storageStoragePolicy概念的“模型”。当然,我们需要正式定义StoragePolicy概念对其模型的要求。在这种情况下,它只是定义一个可索引的data成员变量。

于 2010-02-06T16:20:41.923 回答
2

概念是类型必须满足的一组要求,以便对概念进行建模。

例如,类型TLessThanComparableif 对于一对对象ab类型T,表达式a < b是格式良好的,可转换为bool并引发严格的弱排序关系。该类型int是 的模型的示例LessThanComparable

概念可以形成细化层次结构。如果 的要求是 的要求的超集,则概念A是概念的改进。例如,是对 的改进。BABBidirectionalIteratorForwardIterator

概念用于限制模板可以专门化的类型集。例如,该std::sort算法可以接受一对对象,只要它们对RandomAccessIterator.

std::vector<int> vec;
std::list<int> list;

// OK, std::vector<int>::iterator is a model of `RandomAccessIterator`.
std::sort(vec.begin(), vec.end());

// error, std::list<int>::iterator is only a model of `BidirectionalIterator`.
std::sort(list.begin(), list.end());

请注意,概念是 C++ 标准和各种其他文档中使用的非正式对象。该语言不直接支持概念(尚未)。

于 2010-02-06T16:04:54.580 回答
2

Ao SGI 文档中提到的“模型”是指在 C++0x 提案中作为“概念”引入的内容:它的编译时等同于 OO 建模中的“接口”。它总结了对模板参数的通用代码提出的要求。

作为一个例子,你可以说函数的OutputIterator参数std::transform应该实现operator++()并且operator=( T )为了函数工作。

策略是另一回事:它使算法可以从外部改变。一个很好的例子是Allocatorstl 容器中使用较少的参数:它告诉算法如何分配内存。如果愿意,可以制作一个std::vector<int, AllocateOnCloud>,其中所有vector函数将在云中分配内存而不是在堆上。(请注意,我不倾向于实现这个分配器)。

于 2010-02-06T16:09:24.793 回答