继续我对concepts
的研究,在下面的例子中:
template <typename t>
concept c = requires(t p_t) {
{ p_t.f() } -> std::same_as<int>;
};
template <c t_c> int m1(t_c p_c) { return p_c.f(); }
template <c t_c> int m2() { return t_c::f(); }
struct a {
int f() { return 3; }
};
struct b {
static int f() { return 4; }
};
int main() {
std::cout << m1(a{}) << std::endl;
std::cout << m2<b>() << std::endl;
}
难道std::cout << m2<b>() << std::endl;
不应该导致编译器错误,因为b
不满足c
?
我使用的是gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0
,没有编译或运行时错误。
2条答案
按热度按时间ffscu2ro1#
概念不是 * 基类 *。你不能(或者至少不应该)基于具有特定签名的函数来定义概念。概念验证 * 表达式 *(或常量表达式)的有效性。
如果
f
是b
类型的静态成员函数,并且您有一个名为t
的b
示例,则通过表达式t.f()
调用b::f
是100%法律的C语法。因此,该概念是满足的。
另外,你的模板函数
m2
是一个骗子。它声称它将使用一个雅阁c
概念的类型,但是它做了一些不属于c
的事情。C20概念不能判断一个被概念约束的函数是否说谎。它所能做的就是检查表达式是否可用。
如果用户想通过静态成员函数来满足这个概念,你 * 不应该关心 *。只要它做了它应该做的事情,让用户有自由来满足他们认为合适的条件。
woobm2wo2#
这将是正确的
concept
,这将导致'a' does not satisfy 'c'