【问题标题】:Satisfied and modeled concept?满意和建模的概念?
【发布时间】:2020-06-25 18:16:48
【问题描述】:

简介

标准规定每个概念都与两个谓词相关:

  1. 谓词“被统计”:当一个概念的计算结果为真时,它被一系列模板参数满足。这几乎是一个语法检查。
  2. 谓词“被建模”:如果 Args 满足 C ([temp.constr.decl]) 并满足在C的规范。 [res.on.requirements]

对于某些概念,使满足的概念建模的要求被清楚地表达了。示例[concept.assignable]

LHS 和 RHS 模型 assignable_from 仅当

  • addressof(lhs = rhs) == addressof(lcopy)
  • [...]

但我想知道句法要求是否也隐含着语义要求。

问题

句法谓词是否隐含了对要建模的概念的要求?

我看到了两种隐含的要求:

  1. 该概念得到满足,因为经过语法检查的表达式是未计算的表达式,如果这些表达式不是未计算的表达式,此类表达式将导致程序格式错误。
  2. 这个概念得到了满足,因为语法检查的表达式不会被计算,但对这些表达式的计算会导致程序具有未定义的行为。

示例

例如,让我们考虑default_initializable 概念,在此处定义:[concept.default.init]

default_initializable 满足 A<int>,但如果 A<int> 类型的变量默认初始化 (demo),则程序格式错误:

template <class T>
struct A { 
    A() {
       f(T{});
       }
    };

static_assert (default_initializable <A<int>>);  // A<int> satisfies default_initializable

A<int> a{}; //compile time error: f not declared in this scope

default_initializable 满足 A 但默认初始化 A 导致未定义的行为(当默认初始化之前没有零初始化时)(演示):

struct A { 
    int c;
    A() {
       c++;
       }
    };

static_assert (default_initializable <A>); // A satisfies default_initializable

auto p = new A;  //undefined behavior: indeterminate-value as operand of operator ++

【问题讨论】:

  • default_initializable 没有语义要求,所以可能不是一个好例子?就像,我猜,“这些操作都没有表现出未定义的行为”,但如果你必须在所有地方重复它,那会非常乏味?
  • @Barry 这正是我的问题。 default_initializable 没有明确的语义要求。但它是否要求默认初始化格式正确并且不会导致未定义的行为?还是default_initializable 是一个纯粹的句法概念?
  • @Oliv: "default_initializable 没有明确的语义要求。但它是否要求默认初始化格式正确且不会导致未定义的行为?" 你的第一句话回答第二个。

标签: c++ language-lawyer c++20 c++-concepts


【解决方案1】:

当一个概念的计算结果为真时,它由一系列模板参数满足。这几乎是一个语法检查。

不,它不是“几乎”任何东西:它句法检查。 requires 子句指定的约束(例如)验证特定语法是否是该类型的合法语法。这就是“满足一个概念”的意思全部

句法谓词是否隐含对要建模的概念的要求?

...不。如果满足一个概念也意味着对该概念进行建模,那么该标准就不需要为这些提供不同的术语。

进行这种区分的关键在于认识到概念语言功能无法指定概念作为概念应封装的所有要求。所以令人满意的概念只是语言部分,而建模概念包括语言不能做的事情。

但这个问题与您的两个示例显示的内容有些不同。您的示例代表了“有效语法”和“可以编译/执行”之间的区别。满足一个概念只关心前者。并且对概念进行建模只关心后者所述语义行为被明确指定。

标准中没有关于隐式语义要求的内容。没有关于“必须能够编译和/或执行概念中的所有表达式/语句才能对其进行建模”的声明。也不是有意的。

尽管我们试图假装它不止于此,但 C++20 中存在的概念只不过是一种更方便的执行 SFINAE 的机制。 SFINAE 无法测试某些表达式内容的可编译/可执行有效性,因此概念也不能。概念也没有试图假装它可以。

【讨论】:

  • 多么令人失望......我希望即使没有公理,这个概念也可以被视为一种引入“更强”类型作为类型理论中使用的类型的方法。我宁愿那个合同!
猜你喜欢
  • 2021-10-01
  • 2016-03-15
  • 2020-01-27
  • 2023-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-15
相关资源
最近更新 更多