只有布尔文字值的概念是格式错误的,不需要诊断吗?

我在完全从任何模板中删除的上下文中玩弄 C++ 概念和函数重载,并偶然发现了这一点:

struct S
{
    int mult(int x) requires (true)  { return x; }
    int mult(int x) requires (false) { return x * 2; }
};

int main()
{
    std::cout << S{}.mult(5) << std::endl;
}

g++ 11 拒绝编译此代码段,因为requires-clauses 可能不会附加到非模板函数。

然而,clang++ 13 对这个代码段很好,但令人惊讶的是它吐出10而不是5我所期望的。

我知道 C++20 标准最近才出炉,所以我完全理解关于概念有很多问题需要解决。

忽略常量字面概念的明显无用,我的问题是:带有 -requires子句的程序是否总是格式错误的false,可能不需要诊断?或者,也许,正如 g++ 所说,我什至根本没有合法的 C++?

回答

您的代码段不是合法的 C++。

[dcl.decl.general]

4 init-declarator 或member-declarator 中的可选requires-clause ([temp.pre]) 仅在声明器声明模板化函数([dcl.fct]) 时才出现。当出现在声明符之后时,requires-clause 被称为尾部 requires-clause。[...]

由于看不到模板(并且没有讨论mult重载是否是模板化函数的余地),因此您的尝试显然是格式错误的。这是可诊断规则的“应该”要求。

所以GCC是正确的。Clang 调用完全不直观的重载是双重错误的。尽管当它接受该计划时它确实出轨了。

  • @CoffeeTime - 我不明白为什么预处理时间会很糟糕,但我可能不明白你在做什么。它可能是另一个问答的主题。

回答

这些是标准的“尾随要求条款”部分中的前两个示例:

void f1(int a) requires true;               // error: non-templated function

template<typename T>
  auto f2(T a) -> bool requires true;       // OK

尽管标准中给出的示例显然是非规范性的,但这些示例使意图非常明确。

本质上,概念只能应用于模板函数(因此您的代码是无效的 C++),但布尔文字(例如,requires true)是完全有效的。

但是,其要求从未得到满足(无论falserequired子句中的文字还是其他方式)的模板似乎格式错误,如本示例所示,


以上是只有布尔文字值的概念是格式错误的,不需要诊断吗?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>