需要在C++ 20功能模板中定位子句
在C ++ 20中,您可以以几种不同的方式编写约束功能模板:
template <typename T>
concept Fooable = true;
template <typename T>
requires Fooable<T>
void do_something(T&); // (1)
template <typename T>
void do_something(T&) requires Fooable<T>; // (2)
根据这个问题,这两种形式是等效的(这一直是我的理解)。
但是,我注意到GCC 12.1认为(1)和(2)是两个不同的函数,而不是(2)是重新分配:可以为这两者提供定义,并尝试调用do_something()然后是模棱两可的( xpace )。
- GCC正确,这是两个不同的功能?
- 如果是这样,两种样式之间的含义是否存在任何技术差异?
编辑:
- 正如评论中指出的那样,链接的问题指出,函数模板声明和定义必须使用相同的“需要样式”。这种限制的原因是什么?
(我隐约回想起要求“正常化”以决定它们何时等效的概念 - 我想在C ++ 20中不再是这种情况吗?)
In C++20, you can write a constrained function template in a couple of different ways:
template <typename T>
concept Fooable = true;
template <typename T>
requires Fooable<T>
void do_something(T&); // (1)
template <typename T>
void do_something(T&) requires Fooable<T>; // (2)
According to the accepted answer in this question, these two forms are equivalent (which has always been my understanding).
However, I notice that GCC 12.1 considers (1) and (2) to be two different functions, rather than (2) being a redeclaration: it's possible to provide definitions for both, and attempting to call do_something()
is then ambiguous (example).
- Is GCC correct, and these are two different functions?
- If so, are there any technical differences in meaning between the two styles?
EDIT:
- As pointed out in the comments, the linked questions states that a function template declaration and definition must use the same "requires style". What is the reason for this restriction?
(I vaguely recall from the Concepts TS days that requirements underwent "normalisation" to decide when they were equivalent -- I guess this is no longer the case in C++20?)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
该领域的措辞有些转移。在C ++ 20中,我们在 [temp。 over.link]/7 :
在您的示例中:
这些在功能上是等效的(基本上是相同的约束),但不是等效的(它们具有不同的模板头 - 模板参数之后的要求子句是该模板参数的一部分模板头),这使得无需诊断不需要。在实践中,由于它们不是同等的,因此它们是不同的超载 - 但是由于它们在功能上等效,因此任何试图呼叫的尝试都是模棱两可的。
正如我在另一个答案中指出的那样,它们具有相同的含义 - 只是您必须坚持使用一种形式的声明和定义,如果您拆分它们。
电流措辞,在戴维斯·赫林(Davis Herring href =“ https://eel.is/c++draft/basic.scope.scope.scope#4.3” rel =“ nofollow noreferrer”> [basic..scope.scope]/4 :
这使得两个
do_something
s 不通电,这使它们成为不同的函数模板。我们不会遇到新的功能等效规则(因此我们不符合诊断,不需要诊断),但是我们只有两个函数模板在所有情况下都必须模棱两可。所以...不是世界上最有用的事情。The wording in this area has moved around a bit. In C++20, we had this rule in [temp.over.link]/7:
In your example:
These are functionally equivalent (they have the same constraints, basically) but not equivalent (they have different template-heads - the requires clause after the template parameters is part of the template-head), which makes this ill-formed no diagnostic required. In practice, because they're not equivalent, they're different overloads - but because they're functionally equivalent, any attempt to call would be ambiguous between them.
As I point out in the other answer, these have the same meaning - it's just that you have to stick with one form for the declaration and the definition if you split them.
The current wording, after Davis Herring's omnibus paper P1787, involves going up to [basic.scope.scope]/4:
This makes the two
do_something
s not correspond, which makes them different function templates. We don't run into the new functionally equivalent but not equivalent rule (so we're not ill-formed, no diagnostic required), but we just have two function templates that are necessarily ambiguous in all cases. So... not the most useful thing in the world.