使用默认模板参数

时间:2017-04-19 21:36:49

标签: c++ c++11 templates variadic-templates template-templates

这个问题最好通过例子询问。假设我想用比较器函数声明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”。我的问题是模板参数。

2 个答案:

答案 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_queuestd::vectorstd::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);
 }