假设的,以前的C++ 0x概念问题

GRB*_*GRB 12 c++ axiom c++11 c++-concepts

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

在阅读了一些关于概念的介绍性材料之后,就像C++ 0x(直到最近)提出它们一样,我在思考一些语法问题时遇到了麻烦.不用多说,这是我的问题:

1)支持特定派生概念的类型(隐式地,通过auto关键字,还是显式地通过concept_maps)是否也需要独立支持基本概念?换句话说,从另一个(例如concept B<typename T> : A<T>)派生概念的行为是否隐含地包含'隐形'需求声明(在B中requires A<T>;)?混淆源于维基百科关于概念的页面,其中指出:

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

这似乎说一种类型只需要满足派生概念的要求,而不一定是基本概念的要求,这对我来说没有意义.我知道维基百科远非一个明确的来源; 以上描述只是一个不好的选择?

2)列出类型名称的概念可以是"自动"吗?如果是这样,编译器将如何自动映射这些类型名称?如果没有,是否有任何其他场合在概念上使用'auto'无效?

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

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;
}
Run Code Online (Sandbox Code Playgroud)

这些类中的任何一个都会匹配SomeType吗?或者是涉及类型名称的概念所必需的concept_map?

3)最后,我很难理解允许定义哪些公理.例如,我是否可以定义一个逻辑上不一致的公理,例如

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

    axiom Inconsistency(T a)
    {
         a * 1 == a * 2;
    }
} 
Run Code Online (Sandbox Code Playgroud)

那会怎么样?这甚至有效吗?

我很欣赏这是一个很长的问题,所以我提前感谢你.

Pav*_*aev 11

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

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

2)是的,typename成员的概念可以是auto.如果这些成员用于相同概念中的功能成员的定义,则可以自动推断出这些成员.例如,value_type迭代器可以推导为它的返回类型operator*.但是,如果类型成员未在任何地方使用,则不会推断出它,因此不会隐式定义.在你的例子中,没有办法推导出SomeType<T>::Type任何一个Dummy或者Dummy1,因为Type概念的其他成员没有使用,所以这两个类都不会映射到概念(事实上,没有类可能自动映射到它).见14.10.1.2/11和14.10.2.2/4.

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

对于您的具体示例(考虑语法差异),这将意味着允许编译器将表达式(a*1)视为(a*2)与语言的"as-if"规则相同(即编译器允许执行任何操作)它想要的优化,只要结果表现得好像没有).然而,编译器无论如何都不需要验证公理的正确性(因此它们被称为公理!) - 它只是将它们用于它们的本质.