如何约束C++函数仅接受任意嵌套的特定类型std::vector?
解决方案:约束函数接受任意嵌套的std::vector
要实现能接受任意嵌套层级std::vector<int>,同时拒绝非int相关vector的函数约束,核心是用递归Concept逐层检查vector的元素类型。以下是完整的实现代码:
#include <vector> #include <type_traits> // 辅助模板:判断类型是否是指定模板的特化 template<class, template<class...> class> inline constexpr bool is_specialization = false; template<template<class...> class Tmpl, class... Args> inline constexpr bool is_specialization<Tmpl<Args...>, Tmpl> = true; // Concept:判断是否是std::vector类型 template<class T> concept IsVector = is_specialization<T, std::vector>; // 核心Concept:递归判断是否是任意嵌套的vector,最终元素为int template<class T> concept IsNestedVectorOfInt = std::is_same_v<T, int> || (IsVector<T> && IsNestedVectorOfInt<typename T::value_type>); // 受约束的函数 template<typename T> requires IsNestedVectorOfInt<T> auto foo(T t) { // 函数逻辑实现 } int main() { std::vector<int> intvec {1, 2, 3}; std::vector<std::vector<int>> vecofvec {{1, 2}, {1, 3}}; std::vector<std::vector<std::vector<int>>> vecofvecofvec {{{1}}, {{2}}}; foo(intvec); // 编译通过:单层vector<int> foo(vecofvec); // 编译通过:两层嵌套vector foo(vecofvecofvec); // 编译通过:任意多层嵌套都支持 std::vector<std::string> vecofstr {"bar", "baz"}; // foo(vecofstr); // 编译失败:元素类型是string,不符合要求 std::vector<double> vecofdouble {1.1, 2.2}; // foo(vecofdouble); // 编译失败:元素类型是double,不符合要求 }
关键逻辑说明
递归Concept的设计
IsNestedVectorOfInt通过两个条件实现递归检查:- 终止条件:当前类型就是
int(处理最内层元素,同时保证递归能正常结束) - 递归条件:如果当前类型是
std::vector,则它的value_type必须也满足IsNestedVectorOfInt(也就是要么是int,要么是嵌套的vector)
- 终止条件:当前类型就是
覆盖任意嵌套层级
递归会逐层拆解每个vector的元素类型,不管嵌套多少层,只要最终元素是int,就能通过约束;反之,只要某一层的元素类型不是int也不是符合要求的vector,就会触发编译错误。通用化扩展(可选)
如果需要支持任意目标类型(比如double、std::string),可以把Concept改成模板形式:template<class T, class Target> concept IsNestedVectorOf = std::is_same_v<T, Target> || (IsVector<T> && IsNestedVectorOf<typename T::value_type, Target>);使用时只需指定目标类型:
template<typename T> requires IsNestedVectorOf<T, int> auto foo(T t) { ... }
内容的提问来源于stack exchange,提问作者HarryP2023
相关产品推荐
相关产品推荐

