C++20 Concepts疑问:更严格约束的模板为何无法匹配函数f?
关于C++20 Concepts模板模板参数约束不兼容的问题解答
我正在学习C++20 Concepts,对如下示例存在疑问:为何使用比要求更严格的概念对函数f进行模板化会报错?换句话说,Integral4概念难道不满足Integral概念吗?
#include <type_traits> #include <concepts> template<typename T> concept Integral = std::integral<T>; template<typename T> concept Integral4 = Integral<T> && sizeof(T) == 4; template<template<Integral T1> typename T> void f(){ } template<typename T> struct S1{}; template<Integral T> struct S2{}; template<Integral4 T> struct S3{}; void test(){ f<S1>(); // OK f<S2>(); // OK // error, S3 is constrained by Integral4 which is more constrained than // f()'s Integral f<S3>(); }
错误信息:
<source>: In function 'void test()': <source>:28:10: error: no matching function for call to 'f<template<class T> requires Integral4<T> struct S3>()' 28 | f<S3>(); | ~~~~~^~ <source>:11:6: note: candidate: 'template<template<class T1> class requires Integral<T1> T> void f()' 11 | void f(){ | ^ <source>:11:6: note: template argument deduction/substitution failed: <source>:28:10: error: constraint mismatch at argument 1 in template parameter list for 'template<template<class T1> class requires Integral<T1> T> void f()' 28 | f<S3>(); | ~~~~~^~ <source>:28:10: note: expected 'template<class T1> class requires Integral<T1> T' but got 'template<class T> requires Integral4<T> struct S3' Compiler returned: 1
这本质是模板模板参数的约束兼容性问题——不是Integral4不满足Integral,而是模板模板参数的约束要求是「反向兼容」的:
- 函数
f的模板参数要求是接受任意满足Integral的类型作为模板参数的模板 - 但
S3的模板参数只接受满足Integral4的类型(比Integral更严格),它无法适配f的要求:f期望传入的模板能接受所有Integral类型,而S3做不到(比如char是Integral但不是Integral4,S3<char>是非法的)
举个通俗的例子:
f要求的是「能装下所有水果的篮子」S3是「只能装苹果的篮子」,它满足「装苹果的篮子」的要求,但不满足「装所有水果的篮子」的要求,所以不能传给f
反过来,如果f的模板参数约束是Integral4,那么传入S2(接受所有Integral)是可以的——因为S2能接受所有Integral4类型,满足更严格的约束。
再看代码里的合法情况:
S1没有约束,自然能接受所有Integral类型,符合要求S2的约束就是Integral,完全匹配f的要求,所以合法
内容的提问来源于stack exchange,提问作者user3882729
相关产品推荐
相关产品推荐

