基础类型与自定义类型的Concept满足差异及代码编译问题答疑
问题原因分析
核心差异来自于**参数依赖查找(ADL)**的行为以及C++模板查找规则:
内置类型与用户定义类型的ADL区别
- 对于
int这类内置类型,编译器不会触发ADL。检查foo(t)时,只会在概念CanInvokeFoo的定义点之前查找已声明的foo重载。 - 对于用户定义类型
A,编译器会触发ADL:查找A所在命名空间(此处为全局)中可见的foo,而查找时机是实例化概念CanInvokeFoo<A>的时候(也就是调用bar(A{})的时刻)。
- 对于
代码声明顺序的影响
在你的代码里:CanInvokeFoo的定义位于foo模板的声明之前。当检查CanInvokeFoo<int>时,编译器找不到任何已声明的foo,因此判定int不满足概念。- 当检查
CanInvokeFoo<A>时,foo模板已经被声明(在bar之后、main之前),通过ADL编译器能找到foo<T>,并推断出foo(A)是可行的,因此A满足概念。
验证与修复
如果把foo的声明提前到CanInvokeFoo定义之前,两种类型都能满足概念:
template <typename T> void foo(T t) {} struct A {}; template <typename T> concept CanInvokeFoo = requires (T t) { { foo(t) }; }; template <CanInvokeFoo T> void bar(T t) { foo(t); } int main() { bar(A{}); bar(123); // 现在可以正常编译 }
内容的提问来源于stack exchange,提问作者MarkB
相关产品推荐
相关产品推荐

