12

序言:我是 C++0x 游戏的后期追随者,最近关于从 C++0x 标准中删除概念的争议促使我更多地了解它们。虽然我明白我所有的问题都是完全假设的——只要概念在未来一段时间内都不是有效的 C++ 代码,如果有的话——我仍然有兴趣了解更多关于概念的知识,特别是考虑到它如何帮助我更全面地理解最近决定背后的优点以及随之而来的争议)

在阅读了一些关于 C++0x (直到最近)提出的概念的介绍性材料之后,我无法将我的思想集中在一些句法问题上。事不宜迟,以下是我的问题:

1) 支持特定派生概念的类型(隐式地,通过 auto 关键字,或显式地通过 concept_maps)是否也需要独立地支持基本概念?换句话说,从另一个概念(例如concept B<typename T> : A<T>)推导出一个概念的行为是否隐含地包含一个“不可见的”需求语句(在 B 内requires A<T>;)?混淆来自关于概念的维基百科页面,该页面指出:

与类继承一样,满足派生概念要求的类型也满足基概念要求。

这似乎是说一个类型只需要满足派生概念的要求,而不必满足基本概念的要求,这对我来说毫无意义。我知道维基百科远不是一个确定的来源;上面的描述只是一个糟糕的选择吗?

2)列出类型名的概念可以是“自动”吗?如果是这样,编译器将如何自动映射这些类型名?如果不是,在其他情况下在概念上使用“自动”是无效的吗?

为了澄清,请考虑以下假设代码:

template<typename Type>
class Dummy {};

class Dummy2 { public: typedef int Type; };

auto concept SomeType<typename T>
{
     typename Type;
}

template<typename T> requires SomeType<T>
void function(T t)
{}

int main()
{
    function(Dummy<int>()); //would this match SomeType?
    function(Dummy2()); //how about this?
    return 0;
}

这些类中的任何一个都与 SomeType 匹配吗?或者对于涉及类型名的概念是否需要一个概念映射?

3)最后,我很难理解允许定义什么公理。例如,我能否有一个概念定义一个逻辑上不一致的公理,例如

concept SomeConcept<typename T>
{
    T operator*(T&, int);

    axiom Inconsistency(T a)
    {
         a * 1 == a * 2;
    }
} 

那会做什么?这甚至有效吗?

我很感激这是一组很长的问题,所以我提前感谢你。

4

1 回答 1

11

我使用了最新的 C++0x 草案N2914(其中仍有概念措辞)作为以下答案的参考。

1)概念就像接口一样。如果您的类型支持一个概念,它也应该支持所有“基本”概念。从类型客户的角度来看,您引用的维基百科声明是有意义的——如果他知道T满足概念Derived<T>,那么他也知道它满足概念Base<T>。从类型作者的角度来看,这自然意味着两者都必须实现。见 14.10.3/2。

2) 是的,有typename成员的概念可以是auto。如果在同一概念的函数成员定义中使用这些成员,则可以自动推导出这些成员。例如,value_typefor 迭代器可以推断为它的返回类型operator*。但是,如果一个类型成员没有在任何地方使用,它就不会被推导,因此不会被隐式定义。在您的示例中,无法推断or ,因为SomeType<T>::Type该概念的其他成员没有使用,因此两个类都不会映射到该概念(实际上,没有类可能自动映射到它)。见 14.10.1.2/11 和 14.10.2.2/4。DummyDummy1Type

3) 公理是规范的一个弱点,它们不断更新以使一些(更多)有意义。就在从草稿中提取概念之前,有一篇论文发生了很大的变化——阅读它,看看它是否对你更有意义,或者你仍然对它有疑问。

对于您的具体示例(考虑语法差异),这意味着编译器将被允许考虑表达式(a*1)与 相同(a*2),以实现语言的“as-if”规则(即编译器允许执行任何它想要的优化,只要结果表现得好像没有)。但是,编译器并不需要以任何方式验证公理的正确性(因此为什么它们被称为公理!) - 它只是将它们视为它们的本来面目。

于 2009-07-29T20:28:25.837 回答