【问题标题】:Hypothetical, formerly-C++0x concepts questions假设的、以前的 C++0x 概念问题
【发布时间】:2009-07-29 20:06:25
【问题描述】:

(序言:我是 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;
}

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

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

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

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

那会做什么?这还有效吗?

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

【问题讨论】:

    标签: c++ c++11 axiom c++-concepts


    【解决方案1】:

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

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

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

    3) 公理是规范的一个弱点,它们不断更新以使其更有意义。就在从草稿中提取概念之前,有一个 paper 发生了相当大的变化 - 阅读它,看看它是否对您更有意义,或者您仍然对它有疑问。

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

    【讨论】:

    • 很好的答案。您证实了我对问题 2) 和 3) 的怀疑,而我从未想过 1) 那样。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 2011-02-11
    • 1970-01-01
    • 1970-01-01
    • 2010-10-04
    • 2011-10-22
    • 1970-01-01
    • 1970-01-01
    • 2011-07-31
    相关资源
    最近更新 更多