这个问题最好通过例子询问。假设我想用比较器函数声明std::priority_queue
。我能做到:
auto cmp_fn = [](const std::string& left, const std::string& right) {
return right < left;
};
std::priority_queue<std::string, std::vector<std::string>, decltype(cmp_fn)> queue(cmp_fn);
有没有办法避免指定中间模板参数以便使用默认值?像
这样的东西auto cmp_fn = [](const std::string& left, const std::string& right) {
return right < left;
};
std::priority_queue<std::string, /* use default */, decltype(cmp_fn)> queue(cmp_fn);
注意:这是我正在做的更复杂的事情的简化示例。请不要回答表格的建议:“只使用std::greater
”。我的问题是模板参数。
答案 0 :(得分:3)
您可以使用:
template <class T, class Comparator>
using dcpq = /*default container priority queue*/
std::priority_queue<T, typename std::priority_queue<T>::container_type, Comparator>;
像
一样使用int main() {
auto cmp_fn = [](const std::string &left, const std::string &right)
{ return right < left; };
dcpq<std::string, decltype(cmp_fn)> queue(cmp_fn);
}
虽然直接写
std::priority_queue<std::string, typename std::priority_queue<T>::container,
decltype(cmp_fn)> queue(cmp_fn);
可能更容易。
答案 1 :(得分:1)
如果您对std::priority_queue
的第二个模板参数的特定解决方案感兴趣,我想您可以某种方式使用typename std::priority_queue<T>::container_type
(例如,请参阅nwp中的解决方案; + 1。)。
如果您对更通用的解决方案感兴趣(不仅针对第二个默认模板类型,不仅针对std::priority_queue
),我想您可以首先开发一个类型特征type_n
来抽取n-列表中的类型
template <std::size_t N, typename T0, typename ... Ts>
struct type_n
{ using type = typename type_n<N-1U, Ts...>::type; };
template <typename T0, typename ... Ts>
struct type_n<0U, T0, Ts...>
{ using type = T0; };
接下来是一个类型特征type_cnt_n
(使用type_n
)来提取模板模板参数的第n个类型参数
template <std::size_t, typename>
struct type_cnt_n;
template <std::size_t N, template <typename ...> class Cnt, typename ... Ts>
struct type_cnt_n<N, Cnt<Ts...>>
{ using type = typename type_n<N, Ts...>::type; };
和最后一个(在nwp的答案之后)make_priority_queue()
函数
template <typename T, typename Cmp>
auto make_priority_queue (Cmp const & cmp)
{ return std::priority_queue<T,
typename type_cnt_n<1U, std::priority_queue<T>>::type, Cmp> { cmp }; }
此解决方案的问题是仅适用于具有仅类型模板参数的模板模板类型(因此适用于std::priority_queue
,std::vector
,std::map
但不适用;使用std::array
)。
以下是一个完整的工作......好吧,一个完整的编译......例子
#include <queue>
#include <iostream>
template <std::size_t N, typename T0, typename ... Ts>
struct type_n
{ using type = typename type_n<N-1U, Ts...>::type; };
template <typename T0, typename ... Ts>
struct type_n<0U, T0, Ts...>
{ using type = T0; };
template <std::size_t, typename>
struct type_cnt_n;
template <std::size_t N, template <typename ...> class Cnt, typename ... Ts>
struct type_cnt_n<N, Cnt<Ts...>>
{ using type = typename type_n<N, Ts...>::type; };
template <typename T, typename Cmp>
auto make_priority_queue (Cmp const & cmp)
{ return std::priority_queue<T,
typename type_cnt_n<1U, std::priority_queue<T>>::type, Cmp> { cmp }; }
int main()
{
auto cmpFn = [](std::string const & l, std::string const &r)
{ return r < l; };
auto pq = make_priority_queue<std::string>(cmpFn);
}