2017-04-19 23 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

あなたは、この使用することができます:直接

std::priority_queue<std::string, typename std::priority_queue<T>::container, 
    decltype(cmp_fn)> queue(cmp_fn); 

を書くことが容易になるかもしれませんが

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

のように使用することが

template <class T, class Comparator> 
using dcpq = /*default container priority queue*/ 
    std::priority_queue<T, typename std::priority_queue<T>::container_type, Comparator>; 

を。

+0

申し訳ありませんが... 'decltype(get_queue_storage(std :: priority_queue {}))'の代わりに 'std :: priority_queue :: container_type'を使うのはどうでしょうか?私はあなたが 'get_queue_storage()'なしでできると思います。 – max66

+0

@ max66うん、それはよりスマートになるでしょう。 – nwp

1

あなたがstd::priority_queueの2番目のテンプレートパラメータの特定のソリューションに興味があるなら、私はあなたには、いくつかの方法でtypename std::priority_queue<T>::container_typeを使用することができたとし(例で、参照、NWPから溶液; 1)。

より一般的なソリューションにご興味のある方(非のみ二デフォルトのテンプレートタイプのため、唯一のstd::priority_queue用以外)、私はあなたが最初のリストからn番目のタイプをestractする型特性type_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

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から回答以下)テンプレートテンプレートパラメータのn番目の型引数を抽出しますこのソリューションの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::mapで、std::vectorで、std::priority_queueで動作しますが、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); 
} 
関連する問題