c++ - 将模板参数约束为仅接受带有 C++20 概念的 std::vector 和 std::list
问题描述
我正在尝试编写一个仅对 std::vector 或 std::list 中的数字进行排序的程序,我为此做了两个概念:
template<typename T>
concept ValidContainer = requires(T a) {
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 = requires(T a) {
ValidContainer<T> && std::same_as<typename T::value_type, int>;
ValidContainer<T> && std::same_as<typename T::value_type, float>;
};
以及对它们进行排序的函数的签名:
void BubbleSort(Sortable auto& collection)
{
// sort algorithm
}
我脑海中出现的问题是,当我通过 a 时std::vector<std::string>
,它不会显示编译错误?
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); // this is ok
BubbleSort(test2); // shouldn't this be a compile error?
return 0;
}
解决方案
这:
template<typename T>
concept ValidContainer = requires(T a) {
std::same_as<T, std::vector<typename T::value_type>>;
std::same_as<T, std::list<typename T::value_type>>;
};
正在检查表达式 std::same_as<T, std::vector<typename T::value_type>>;
是否有效,而不是它也是true
。也就是说,它基本上只是检查那typename T::value_type
是一件事。
在这种形式下,如果你想要一些东西,你必须使用requires
:
template<typename T>
concept ValidContainer = requires(T a) {
requires std::same_as<T, std::vector<typename T::value_type>>;
requires std::same_as<T, std::list<typename T::value_type>>;
};
虽然现在我们要求T
它既是 avector
又是 a 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>>;
虽然这也不是很好,因为现在我们正在拒绝std::vector<T, MyAlloc>
.
这与为什么这是你的约束的问题是分开的 - 为什么你只能排序vector
and list
... 而不能 like deque
or string
or span
or ... ?或者为什么你只限于int
和float
?
您可以对任何可排序的前向范围进行冒泡排序。我会表达为:
template <std::ranges::forward_range R>
requires std::totally_ordered<std::ranges::range_reference_t<R>>
void BubbleSort(R& r);
推荐阅读
- wordpress - Wordpress Ultimate Member:在帐户页面上显示个人资料信息
- python - 通过固定大小的python数据套接字发送整数
- apache - Modsecurity & Apache:如何通过标头限制访问速率?
- events - 最小化 Tcl/Tk 时也启用绑定
- python - 如何处理python和索引中不同大小的列表(列表索引)
- css - 悬停时显示材质复选框动画
- ruby-on-rails - ActionView::Template::Error(数据库和 Ruby 的时区信息不一致
- api - 如何在线获取 Quickbooks 的 EntityID?
- php - php - 使用复选框在循环内更新mysql
- python - devpi 索引中的 toxresult_upload 权限