带有多个模板参数的C ++概念

时间:2017-02-23 10:41:33

标签: c++ templates c++-concepts

Bjarne Stroustrup最近发表了关于C ++ Concepts的report,他提到了一些让我感到惊讶的事情。示例(在第7.1节中)使用“简写模板表示法”,基本上是这样的:

void foo1(auto x,auto y);                // x and y may have different types  (1)
void foo2(SomeConcept x,SomeConcept y);  // x and y must have the same type   (2)

就我个人而言,这似乎非常反直觉;事实上,我希望foo2接受不同类型的值x,y,只要各个类型满足SomeConcept。请注意,程序员始终可以通过编写以下内容之一来明确指定其意图:

template <SomeConcept T> void foo2(T x, T y);                   // (3)
template <SomeConcept T1,SomeConcept T2> void foo2(T1 x,T2 y);  // (4)

直观地说,我希望(2)中的简写符号等同于(4),因此更符合无约束模板(1)的含义。有人可以解释这个问题并解释这个设计决定背后的理由吗?

一些评论:

  • afaik,泛型lambdas(在C ++ 14中)已经允许类似于(1)的语法。因此,一致性要求(1)应该接受具有不同类型的输入变量,因为通用lambda就是这样。
  • Stroustrup在这种模板的上下文中提到了经典的“迭代器对”。但是,我认为这是一个相当弱的论据,因为(i)这只是一个用例和(ii)afaik,C ++ 17引入(迭代器,哨兵)对,这迫使通用代码使用两种不同的类型

2 个答案:

答案 0 :(得分:2)

我能找到的最早的论文在当前的Concepts提案的上下文中提到了简洁的语法N3580,这在§6.2.2中提供了这个基本原理:

  

如果我们需要两个相同概念的参数类型怎么办?考虑

void sort(Ran p, Ran q);
     

为此,pq必须属于同一类型,这就是规则。默认情况下,如果对两个参数使用相同的约束参数名称,则这些参数的类型必须相同。我们选择重复使用受约束的参数名称意味着“相同类型”,因为(在大多数环境中)是最常见的情况,这里的目标是优化   最简单案例的简洁表示法。此外,约束参数是名称   类型的,并且具有两个类型名称指的是同一范围内的不同类型   会导致混乱。

Tony van Eerd和Boton Ballo提议改变这个含义:P0464。本文提供了支持当前意义的两个论点,一个类似于Sutton等人提出的一个论点,一个正交:

  

使用频率
  可以认为,你并不经常需要一个函数,它接受两个可能不同类型的参数,这些参数满足相同的概念,而两种类型之间没有额外的关系。

     

与定义检查的互动
  还可以认为,此更改将鼓励模板作者编写受约束的模板,因为即使在应该对参数类型存在额外约束的情况下,他们也会选择使用简洁的R foo(ConceptName, ConceptName);形式。增加约束不足的模板会使定义检查的引入更加困难,因为约束不足的模板不会通过定义检查。

我不熟悉支持当前语法的任何其他论据,但如果您愿意,请随时通过电子邮件将Tony和Botond发送到他们的论文中。

答案 1 :(得分:1)

为标记此问题或在Google上找到该问题的人提供快速更新。

在2018年3月于杰克逊维尔举行的C ++标准会议之前,这里讨论的问题已被解决-显然是默默地解决了。引用Botond's trip report

  

顺便说一句,似乎没有太多讨论就解决的一个话题是独立解决方案一致解决方案的问题;也就是说,如果您在AFT中有两个相同概念的用法(如void foo(Number, Number);),是要求它们是相同的具体类型(“一致”),还是两个都可能为该概念建模的潜在不同类型(“独立”)。 Concepts TS具有一致的分辨率,但是许多人更喜欢独立的分辨率。不久前,我与人合着了一篇论文,主张独立解决方案。随后,另一篇论文和Sortable{S}提案的一部分也进一步强化了这种观点。令我高兴的是,这个话题从未真正被正式讨论过并投票过。随着时间的流逝,独立解决方案的想法似乎慢慢地赢得了人们的青睐,因此在本次会议上,这似乎已经完成了,实际上,任何进入C ++ 20的AFT提案都将具有分辨率。