c++ - 概念要求和非直接上下文

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

我正在学习 C++ 概念,并试图理解为什么 the following does not compile (这只是一个证明这一点的琐碎且无意义的示例;已使用 GCC-11.1 进行测试):

#include <iostream>

struct non_negatable {
};

template <class T>
auto negate(T a) {
    return -a;
}

template <class T>
concept is_negatable = requires(T t) {
    //just `-a;` would do the job of course
    negate(t);
};

template <class T>
auto do_negate(T) {
    std::cout << "here we are\n";
}

template <is_negatable T>
auto do_negate(T t) {
    return negate(t);
}

int main() {
    non_negatable x;
    do_negate(x);
}

上述概念试图调用函数模板,其实现 将无法编译。这一事实导致了“硬错误”,而不是使概念失败。

我猜它是这样工作的,因为概念要求可能仅因表达式的“直接上下文”格式不正确(就像我们可以在 SFINAE 中观察到的那样)而失败。

我的理解对吗?标准在哪里描述了这一点?有没有一种方法可以使基于函数模板实现格式不正确的概念“失败”?

最佳答案

首先,正如您所提到的,negate<non_negatable>不是替换失败,因为错误不在 immediate context 中的功能,因此它的格式错误。来自 13.10.3.1/8 C++20 标准:

If a substitution results in an invalid type or expression, type deduction fails.

An invalid type or expression is one that would be ill-formed, with a diagnostic required, if written using the substituted arguments.

[Note 4: If no diagnostic is required, the program is still ill-formed. Access checking is done as part of the substitution process. — end note]

Only invalid types and expressions in the immediate context of the function type, its template parameter types, and its explicit-specifier can result in a deduction failure.

[Note 5: The substitution into types and expressions can result in effects such as the instantiation of class template specializations and/or function template specializations, the generation of implicitly-defined functions, etc. Such effects are not in the “immediate context” and can result in the program being ill-formed. — end note]

其次,7.5.7.1/6说:

[...]

[Note 1: If a requires-expression contains invalid types or expressions in its requirements, and it does not appear within the declaration of a templated entity, then the program is ill-formed. — end note]

[...]

所以,您的理解对我来说似乎是正确的。但是,您在上一个问题中要问的问题归结为是否有一种方法可以使模板函数主体中的无效表达式导致替换失败而不是格式错误的程序。我不认为这是可能的。

关于c++ - 概念要求和非直接上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70940008/

相关文章:

c++ - 有没有更好的方法来反转循环中的 bool 值?

c++ - 为什么不透明枚举声明不是定义?

c++ - 有关将char指针转换为其他类型指针的问题

永远不会执行的代码可以调用未定义的行为吗?

c++ - 使用结果启动异步操作

C++20 string/u8string 和 string_view/u8string_view 之间的转换

c++ - 控制符号可见性的标准方法

c++ - MinGW/CxxTest 奇怪的错误

c++ - 如何去除opencv中的二进制图像噪声?

c++ - 关于推导转换函数模板参数的几个问题