4

这是一个库实现者在我们等待(希望)传入概念时定义宏的好主意吗?这种方法的优点和缺点是什么?

宏示例(由 A. Stepanov 撰写):

#define TotallyOrdered typename
#define Pointer typename
#define Number typename
#define Unsigned typename
#define Integral typename
#define InputIterator typename
#define OutputIterator typename
#define ForwardIterator typename
#define BidirectionalIterator typename
#define RandomAccessIterator typename
...

示例用法(来自我):

template<ForwardIterator It>
It min_element(It first, It last) { ... }

想法:

  • 虽然没有概念,但它是一个普通的旧模板代码
  • 当概念最终到达时,如果概念名称不同,您可以删除所有宏或重命名它们(您可以在任何体面的 IDE 中轻松执行此操作),然后删除或只是将这些宏重新实现为概念表达式
  • 在不重写复杂的模板代码的情况下利用未来的功能
  • 即使是现在,“类型化”模板参数也允许更好地理解代码并解锁开发静态概念检查工具的可能性

长话短说:A. Stepanov在 Amazon A9 的几个系列课程中,他使用这些宏在课堂上实现的算法的模板参数列表中替换关键字。被这个“面向指针的程序员”和所有 C++ 库的老大师迷住了,我开始在任何地方使用这些宏。最近有人指出宏是丑陋的(而且,迭代器有点过时了,但这是另一个故事)。所以现在我正在寻找其他专家对这种方法的建议。 typename

有问题的库示例:标准库的 GPU 加速版本(具有高性能计算的东西,如数组结构、压缩迭代器等)、线性代数库、树状数据结构、新算法函数

4

3 回答 3

6

一个巨大的缺点是您的代码会撒谎


我更喜欢什么

该代码根本不使用概念,但是如果/当它们存在时,您可以更改它以在将来使用它们。

我不喜欢什么

该代码根本不使用概念,但看起来确实如此。无法想象比这更危险的事情了。将灌输给维护者的一种巨大的虚假安全感!


你的想法无论如何都行不通。当概念出现时,您将不可避免地发现您在某个地方犯了一些错误,而这些错误可能是您的旧编译器无法诊断出来的。您仍然需要更改您的代码

现在,只需像往常一样记录类型的前提条件/约束。

于 2016-01-02T02:02:43.710 回答
2

正如其他人所说,这听起来不是一个好主意。该标准通常使用模板参数的名称来描述它预期具有的属性。因此,例如,该算法all_of被描述为

template <class InputIterator, class Predicate>
bool all_of(InputIterator first, InputIterator last, Predicate pred);
于 2016-01-02T13:20:04.480 回答
0

您可能只想拥有一个宏,例如CONCEPTS,并在如下代码中使用它:

#ifdef CONCEPTS
// you concept based code
#else
// your temp workaround code
#endif

这样你就可以使用你的构建工具(例如makefile)来控制是否使用概念。

于 2016-01-02T01:01:30.137 回答