2017-04-19 168 views
1

這個問題最好通過示例來提問。假設我想用比較器函數聲明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」。我的問題是關於模板參數。

+1

不大,但是模板別名肯定會似乎可行的,不是嗎? – WhozCraig

回答

2

您可以使用此:

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); 

可能會更容易。

+0

對不起,但... ...使用'std :: priority_queue :: container_type'而不是'decltype(get_queue_storage(std :: priority_queue {}))'?我想你可以不用'get_queue_storage()' – max66

+0

@ max66是的,那會更聰明。 – nwp

1

如果您對第二個模板參數std::priority_queue的特定解決方案感興趣,我想您可以以某種方式使用typename std::priority_queue<T>::container_type(例如,請參閱nwp; +1的解決方案)。

如果你有興趣在一個更通用的解決方案(非只爲第二默認模板類型,非只爲std::priority_queue),我想你可以先制定一個類型特徵type_n從列表estract第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); 
} 
直接