C++20多模板参数下auto结合concept的用法咨询
问题解答
首先,你的多参数concept定义写法有误,正确的多参数concept定义格式应该是这样的:
template<typename T1, typename T2> concept MyConcept = /* 此处填写涉及T1、T2的约束表达式 */;
你原本写的concept MyConcept<T1, T2>是错误语法,concept名称后不需要附加模板参数列表,模板参数列表只需放在template<>声明中即可。
为什么void func(MyConcept auto c)不合法?
Concept auto这种缩写语法是专门为单参数concept设计的——它会自动推导一个模板参数T,并约束Concept<T>成立。但多参数concept需要至少两个模板参数,这种语法无法传递多个参数,因此直接这么写不符合C++标准。
多参数concept的简化写法分两种场景:
场景1:固定部分参数,仅推导剩余参数
如果多参数concept中有部分参数是固定类型,剩下的一个参数由函数参数推导,可通过绑定固定参数将多参数concept转化为单参数约束,再用auto写法。
比如定义一个判断类型可转换性的多参数concept:
#include <concepts> template<typename From, typename To> concept ConvertibleTo = std::convertible_to<From, To>;
若需要一个接受能转换为int的任意类型参数的函数,可写为:
void func(ConvertibleTo<int> auto c) {}
这里ConvertibleTo<int>相当于单参数约束,auto推导的类型会作为From参数,约束ConvertibleTo<From, int>成立。
场景2:函数多个参数对应concept的多个模板参数
如果函数需要两个(或多个)参数分别对应多参数concept的不同模板参数,比如定义一个要求两参数相加结果为int的concept:
#include <concepts> template<typename T1, typename T2> concept AddableToInt = requires(T1 a, T2 b) { {a + b} -> std::same_as<int>; };
此时有两种简化写法:
写法1:缩写模板 + requires子句
用auto声明函数参数,末尾通过requires子句直接应用多参数concept:
void func(auto a, auto b) requires AddableToInt<decltype(a), decltype(b)> {}
写法2:显式模板参数 + concept约束
在模板参数列表中直接用concept约束参数,写法更简洁:
template<AddableToInt T1, T2> void func(T1 a, T2 b) {} // 等价于完整写法: // template<typename T1, typename T2> // requires AddableToInt<T1, T2> // void func(T1 a, T2 b) {}
内容的提问来源于stack exchange,提问作者Roger World
相关产品推荐
相关产品推荐

