使用C++20 concepts限定模板仅接受std::vector/std::list约束不生效
问题原因
你写的concept存在两个核心错误,导致约束完全没有生效:
- 误用requires表达式:你把
std::same_as这类编译期布尔判断放在了requires的花括号内,此时requires只会检查花括号内的表达式本身能否合法编译,不会校验表达式的返回值是否为true。只要类型T存在value_type成员,不管std::same_as的判断结果是真还是假,整个requires表达式都会返回true,所以std::vector<std::string>也能通过ValidContainer校验。 - 逻辑运算符错误:你在
ValidContainer中用默认的&&逻辑判断容器类型,要求类型同时是std::vector和std::list,这显然不可能成立;在Sortable中同样用&&判断元素类型,要求元素同时是int和float,也没有符合要求的类型。哪怕你去掉requires块,这样的逻辑也会导致没有类型能满足你的约束。
修改方案
concept可以直接接编译期布尔表达式,不需要包裹requires块,按你的需求修改如下:
- 先修正
ValidContainer,用||判断容器是std::vector或者std::list:
template<typename T> concept ValidContainer = std::same_as<T, std::vector<typename T::value_type>> || std::same_as<T, std::list<typename T::value_type>>;
- 再修正
Sortable,判断容器满足ValidContainer,且元素类型是int或者float:
template<typename T> concept Sortable = ValidContainer<T> && (std::same_as<typename T::value_type, int> || std::same_as<typename T::value_type, float>);
修改后传入std::vector<std::string>会触发预期的编译错误,完整可测试代码如下:
#include <vector> #include <list> #include <string> #include <concepts> template<typename T> concept ValidContainer = std::same_as<T, std::vector<typename T::value_type>> || std::same_as<T, std::list<typename T::value_type>>; template<typename T> concept Sortable = ValidContainer<T> && (std::same_as<typename T::value_type, int> || std::same_as<typename T::value_type, float>); void BubbleSort(Sortable auto& collection) { // 排序逻辑实现 } int main() { std::vector<int> test = { 32, 3, 6, 8, 2, 5, 0, 43, 67, 1 }; std::vector<std::string> test2 = { "first", "second", "third" }; BubbleSort(test); // 正常编译通过 BubbleSort(test2); // 触发编译错误,符合预期 return 0; }
内容的提问来源于stack exchange,提问作者Iván Ayala
相关产品推荐
相关产品推荐

