2017-09-25 5 views
1

INDEXの第1パラメータを返すテンプレート関数を作成するにはどうすればよいですか?INDEXの第1パラメータを返すテンプレート関数

template <int INDEX, typename ...PARAMETERS> 
auto &&select(PARAMETERS&& ...parameters); 

私は「ヘビー級」解決策を知っている:それはコンパイラの最適化プログラムに大きく依存して私は、本当にこのソリューション好きではない

template <int INDEX, typename ...PARAMETERS> 
auto &&select(PARAMETERS&& ...parameters) { 
    std::tuple<PARAMETERS&&...> t(parameters...); 
    return std::get<INDEX>(t); 
} 

を。また、不必要なタプルのためにデバッグビルドの速度が遅くなる可能性があります。この問題のための任意のより良い(より軽量、スケーラブルな)解決策はあるの

template <int INDEX> 
struct SelectNthParameter; 

template <> 
struct SelectNthParameter<0> { 
    template <typename PAR0, typename ...TAIL> 
    static PAR0 &&value(PAR0 &&par0, TAIL&& ...tail) { 
     return forward<PAR0>(par0); 
    } 
}; 

template <> 
struct SelectNthParameter<1> { 
    template <typename PAR0, typename PAR1, typename ...TAIL> 
    static PAR1 &&value(PAR0 &&par0, PAR1 &&par1, TAIL&& ...tail) { 
     return forward<PAR1>(par1); 
    } 
}; 
// add more template specializations for 2...inf 

または私は、非常にスケーラブルではない(が、性能-OK)ソリューションを知っていますか?ここで

+0

おそらく、再帰的なテンプレートが必要です。これは、 '<0>'の特殊なケースと、 'INDEX-1'でそれ自身を呼び出す一般的なケースです。これが 'std :: get'の実装方法です。結局、私はそれがあなたの "ヘビー級"アプローチとまったく同じコードを生成するだろうと思う。 –

答えて

0

は、私が思いついたものを何も地球粉砕だ:

template <int INDEX> 
struct SelectNthParameter { 
    template <typename HEAD, typename ...TAIL> 
    __attribute__((always_inline)) 
    static auto &&value(HEAD &&head, TAIL &&...tail) { 
     return SelectNthParameter<INDEX-1>::value(tail...); 
    } 
}; 

template <> 
struct SelectNthParameter<0> { 
    template <typename HEAD, typename ...TAIL> 
    __attribute__((always_inline)) 
    static auto &&value(HEAD &&head, TAIL &&...) { 
     return std::forward<HEAD>(head); 
    } 
}; 

always_inlineの、このソリューションはtupleよりも効率的である(デバッグでは、唯一の2のasm命令が各パラメータのために生成され、ビルドをはるかのでtupleバージョン未満)。

これがリリースビルドで最適化されることをより確実にすることができます。私はこのソリューションにも100%満足しているわけではありませんが、これは質問の例よりも優れています。

関連する問題