这是我所拥有的功能,它按对的第一个元素对向量对进行排序。
std::vector<std::pair<int,std::string>>
sort_pairs(std::vector<std::pair<int,std::string>>&& items)
{
std::sort(std::begin(items),std::end(items));
return items;
}
但是当我尝试将其推广为接受任何类型的分配器和该对的任何类型时,我都会收到一堆错误(将其粘贴到此处太多了)。我使用右值引用作为参数,因为该函数在其他函数内部调用,使用复制参数也可以,但是我认为效率较低。这是我尝试过的一些方法。
template <typename Allocator,
typename P1 = typename Allocator::value_type::first_type,
typename P2 = typename Allocator::value_type::second_type>
Allocator<std::pair<P1,P2>> sort_pairs(Allocator<std::pair<P1,P2>>&& items)
{
std::sort(std::begin(items),std::end(items));
return items;
}
如果您在代码中添加一些c ++ 20提示,我们将不胜感激。像需求一样。
表达Allocator
,您应该使用的是“ template template parameter”。
如下
template <template <typename...> class Allocator,
typename P1, typename P2>
Allocator<std::pair<P1, P2>>
sort_pairs (Allocator<std::pair<P1, P2>> && items)
{
std::sort(std::begin(items),std::end(items));
return items;
}
从C ++ 17开始,可以使用typename
代替class
进行定义
// ..............................VVVVVVVV
template <template <typename...> typename Allocator,
但是class
仍然有效,恕我直言,更可取。
请注意,Allocator
会拦截std::vector
(模板类,而不是std::vector<std::pair<int, std::string>>
的特定专业化,因此您无法像示例中那样从中提取P1
和P2
// ....................VVVVVVVVV not usable this way
typename P1 = typename Allocator::value_type::first_type
您应该写
typename Allocator<std::pair<P1, P2>>::value_type::first_type
但是,显然,您不能使用它为P1
赋予默认类型,因为您必须知道P1
。
幸运的是,可以从P1
参数推导出P2
和items
,因此您不需要默认类型。
底层类型是一对显着的事实吗?该算法的主体没有以任何方式使用它。我们可以从以下开始:
template <typename R>
std::decay_t<R> sort(R&& items)
{
std::sort(std::begin(items),std::end(items));
return items;
}
在C ++ 20中,我们可以通过要求R
是其迭代器可排序的范围来适当地约束-是的,有一个概念:
template <std::ranges::range R>
requires std::sortable<std::ranges::iterator_t<R>>
std::decay_t<R> sort(R&& items)
{
std::sort(std::ranges::begin(items), std::ranges::end(items));
return items;
}
如果您真的想要求这是成对的范围,则可以将其添加为单独的约束:
template <std::ranges::range R>
requires std::sortable<std::ranges::iterator_t<R>> &&
is_specialization_of<std::ranges::range_value_t<R>, std::pair>
std::decay_t<R> sort(R&& items)
{
std::sort(std::ranges::begin(items), std::ranges::end(items));
return items;
}
我将is_specialization_of
的实现留作练习。