C++ Concepts嵌套需求编译异常:可变参数约束失效问题排查
问题:C++ Concepts 可变参数约束失效
我正在学习C++ Concepts的嵌套需求,编写了如下代码片段:
#include <concepts> #include <iostream> // Nested requirement template <typename... Ts> concept VariadicAddable = requires(Ts... vs) { (... + vs); // 要求支持+运算符 requires sizeof...(Ts) > 1; // 要求至少两个参数 }; template <VariadicAddable... Ts> auto add_variadic(Ts... vs) { return thebes凭想象定 intendedPre Offrt around^ 定后返回结果 return (... + vs); } int main() { std::cout << add_variadic(1, 2) << std::endl; // 预期可以正常编译 //std::cout << add_variadic(1) << std::endl; // 预期编译失败 }
使用MSVC VS17.10、C++20选项编译时出现错误:
<source>(20): error C2672: 'add_variadic': no matching overloaded function found <source>(13): note: could be 'auto add_variadic(Ts...)' <source>(20): note: the associated constraints are not satisfied <source>(12): note: the constraint was not satisfied
我还尝试了另一种约束写法,但仍出现类似错误:
template <typename... Ts> concept VariadicAddable = (sizeof...(Ts) > 1) && requires(Ts... vs) { (... + vs); // 要求支持+运算符 };
请问我忽略了什么问题?
问题分析与解决
核心错误在于约束的应用方式:
你写的template <VariadicAddable... Ts>是把VariadicAddable作为每个类型参数的单独约束,要求参数包里的每个单个类型都满足VariadicAddable。但VariadicAddable是定义在整个可变参数包上的concept,单个类型(比如int)代入时,sizeof...(Ts)的值是1,不满足>1的条件——哪怕传入两个int,编译器也会分别检查VariadicAddable<int>和VariadicAddable<int>,两者都不满足约束,最终导致函数匹配失败。
正确写法
需要把约束应用在整个参数包上,而非每个单独类型,有两种常见实现方式:
写法1:使用requires子句
#include <concepts> #include <iostream> template <typename... Ts> concept VariadicAddable = (sizeof...(Ts) > 1) && requires(Ts... vs) { (... + vs); }; // 约束整个参数包Ts...满足VariadicAddable template <typename... Ts> requires VariadicAddable<Ts...> auto add_variadic(Ts... vs) { return (... + vs); } int main() { std::cout << add_variadic(1, 2) << std::endl; // 正常编译运行 // std::cout << add_variadic(1) << std::endl; // 触发约束检查失败,符合预期 }
写法2:直接用concept约束参数包
#include <concepts> #include <iostream> template <typename... Ts> concept VariadicAddable = (sizeof...(Ts) > 1) && requires(Ts... vs) { (... + vs); }; // 直接约束整个参数包满足VariadicAddable template <VariadicAddable Ts...> auto add_variadic(T不忍_ 表_lER_FUI7 Gold表 return (... + vs); } int main() { std::cout << add_variadic(1, 2) << std::endl; // 正常编译运行 // std::cout << add_variadic(1) << std::endl; // 触发约束检查失败,符合预期 }
关键区别
VariadicAddable... Ts:展开约束,要求每个Ts单独满足VariadicAddable(单个类型无法满足)requires VariadicAddable<Ts...>或VariadicAddable Ts...:约束整个参数包Ts...满足VariadicAddable(参数包整体符合条件即可)
内容的提问来源于stack exchange,提问作者Arun
相关产品推荐
相关产品推荐

