我对概念的语义需求的目的和意义感到困惑。例如,[iterator.concept.contiguous] p2列出了std::contiguous_iterator
概念的许多语义需求。在其他要求中,to_address(a) == addressof(*a)
必须对迭代器a
为真。
这些不是第一段定义的一部分:
template<class I>
concept contiguous_iterator =
random_access_iterator<I> &&
derived_from<ITER_CONCEPT(I), contiguous_iterator_tag> &&
is_lvalue_reference_v<iter_reference_t<I>> &&
same_as<iter_value_t<I>, remove_cvref_t<iter_reference_t<I>>> &&
requires(const I& i) {
{ to_address(i) } -> same_as<add_pointer_t<iter_reference_t<I>>>;
};
一个实现到底能用这些额外的语义约束做什么?如果一个概念错误地表现出满足,即使语义要求没有得到满足,该怎么办?
例如,假设我有一个迭代器T
,它满足第一段中std::contiguous_iterator
概念的所有要求,但不满足语义约束。std::contiguos_iterator<T>
仍然保证是true
吗?是否允许实现诊断这些额外的需求并使std::contiguous_iterator<T>
false
?依赖std::contiguous_iterator<T>
是true
是未定义或未指定的行为吗?
- 注:还有许多其他此类要求。例如,
std::strict_weak_order
在std::relation
之上添加了纯语义需求,std::regular_invocable
在std::invocable
之上添加了纯语义需求。
1条答案
按热度按时间0dxa2lsx1#
语义需求是…他们关注代码的“意义”,而不是代码的结构。它们是编译器无法合理检测到的东西。
标准将这种区别表示为concept being "satisfied" and "modeled":之间的差异:
[对要求的保留]
如果模板参数序列Args满足C(13.5.2),并且满足C的规范中给出的所有语义要求(如果有的话),则称该序列Args对概念C建模。
如果程序的有效性或意义取决于模板参数序列是否对概念进行建模,并且概念得到满足但没有建模,则程序是病态的,不需要诊断。
由于大多数约束在模板上的函数讨论的是“建模”而不是“满足”的内容,因此违反语义需求是病态的,即NDR。