本文介绍了C ++概念复合要求和返回类型要求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我上一次在GCC上使用C ++概念并使用fconcepts标记以下代码段可用

The last time I used C++ concepts with GCC and the fconcepts flag the following snippet used to work

template <typename T, typename U>
concept equality_comparable = requires(T a, U b) {
  { a == b } -> bool;
  { a != b } -> bool;
};

显然不再是这种情况了,返回类型要求复合要求之后,现在只能包含类型约束。如果我没记错的话,这基本上意味着要使用另一个概念来满足 return-type-requirement

Apparently this is no longer the case and a return-type-requirement after a compound requirement can now only contain type constraints. If I'm not mistaken this basically means using another concept to satisfy the return-type-requirement.

因此,完全可读且( C ++标准)的简短摘要成为

So the perfectly readable and (for C++ standards) short snippet becomes

template <typename From, typename To>
concept convertible_to = std::is_convertible_v<From, To>;

template <typename T, typename U>
concept equality_comparable = requires(T a, U b) {
  { a == b } -> convertible_to<bool>;
  { a != b } -> convertible_to<bool>;
};

当然,这甚至不是完整的实现,但现在暂时忽略它。有人可以向我解释为什么委员会决定改变这一点吗?我个人认为,convertible_to概念中的隐式使用的模板参数非常烦人和令人困惑。

Of course this isn't even a full implementation, but let's ignore that for now. Could someone maybe explain to me why the committee decided to change that? Personally I find that "implicitly used template parameter" in the convertible_to concept extremely irritating and confusing.

推荐答案

嗯,这实际上是什么?意思是:

Well, what does this actually mean:

template <typename T, typename U>
concept equality_comparable = requires(T a, U b) {
  { a == b } -> bool;
  { a != b } -> bool;
};

这是否意味着 a == b 必须的类型完全是 bool ,或者这意味着如果衰减该类型,则会得到 bool (即 const bool bool& 都可以),或者这意味着可以转换为 bool (即 std :: true_type 可以)?我认为语法完全不清楚-特定概念可能会有意义地期望这三个中的任何一个(例如指出,当时 Same< T> 在概念上为 ConvertibleTo< T >。

Does it mean a == b must have type exactly bool, or does it mean if you decay the type you get bool (i.e. const bool or bool& are ok), or does it mean convertible to bool (i.e. std::true_type is ok)? I don't think it's at all clear from the syntax - and any one of these three could be meaningfully desired by a particular concept (as P1452 points out, at the time, the ratio of Same<T> to ConvertibleTo<T> in concepts was 40-14).

本文还继续指出,在Concepts TS中,->类型存在,我们还可以编写类似 vector< Concept> ...或->之类的东西。 vector< Concept> 作为要求。这是一种类型,但是使用我们在decltype(())语义时,会表现非常困难。 jtc1 / sc22 / wg21 / docs / papers / 2018 / p1084r2.pdf rel = nofollow noreferrer> P1084 。

The paper also goes on to point out that in the Concepts TS, where -> Type existed, we also had the ability to write something like vector<Concept>... or -> vector<Concept> as a requirement. That's a type, but would behave very difficultly with the decltype(()) semantics we adopted in P1084.

基本上,我认为完全可读的代码段实际上不是-该语法有多种潜在含义,根据上下文,所有这些含义都可能是所需的含义。当时最常用的一个( same_as< bool> )甚至不是我们想要的一个( convertible_to< bool> )。

Basically I don't think the "perfectly readable" snippet actually is - there are multiple potential meanings for that syntax, all of which can be the desired meaning depending on context. And the most commonly used one at the time (same_as<bool>) isn't even the one we want here (convertible_to<bool>).

在C ++中是新颖的,但是我个人觉得在这些情况下它读起来很好。看到:

It's novel in C++, but I personally find it reads quite nicely in these cases. Seeing:

{ a == b } -> convertible_to<bool>;

只需按照要求精确读取: a == b 必须是可转换为 bool 的有效表达式。对于一元概念,它使用法相当不错,因为您可以使用它们代替有些无意义的 typename / class 关键字:

Just reads exactly as the requirement: a == b needs to be a valid expression that's convertible to bool. For unary concepts, it makes the usage quite nice since you can use them in place of the somewhat meaningless typename/class keyword:

template <range R>
void algo(R&& r);

与其他语言没什么不同。例如,在Rust中:

Which isn't that different from other languages. Like, in Rust for instance:

fn algo<I: Iterator>(i: I)

那里的隐式使用的模板参数是如此隐含,甚至不属于,它也是隐含的:

There the "implicitly used template parameter" is so implicit that it's not even part of the trait declaration, it's implicit there too:

pub trait Iterator { ... }

因此,即使使用更长格式的语法,也要编写,其中I:迭代器,而在C ++中,您仍然要编写 range< R>

So even with a longer-form syntax, you'd write where I: Iterator whereas in C++ you'd still write requires range<R>.

这与原始问题并不严格相关,但我发现添加其他颜色很有趣。

This isn't strictly related to the original question, but I just find it interesting to add for some other color.

这篇关于C ++概念复合要求和返回类型要求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-21 10:58