1

私の理解では、テンプレートの引数推定は関数テンプレートのみを対象としていますが、関数テンプレートでは部分的な特殊化は許可されていません。両方を達成する方法はありますか?

私は基本的に、署名を使用して関数のようなオブジェクト(ファンクタにすることができます)を実現したいと考えています

template<class InputIterator1, class InputIterator2, class OutputIterator, int distribution>
void GetQuantity(InputIterator1 frist1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, double supply, double limit);

配布の価値に応じて、このテンプレートをいくつか特殊化したいと考えています。そして、この関数を呼び出すとき、基本的にすべての型パラメーターを指定する必要はありません。なぜなら、それらは多くの型パラメーターであるためです (したがって、引数の推定が必要です)。

4

2 に答える 2

3

配布時にテンプレート化されたファンクターを使用してこれを実現し、次の呼び出しで推論を実行できますoperator()

template<int distribution>
struct GetQuantity {
    template<class InputIterator1, class InputIterator2, class OutputIterator>
    void operator()(
        InputIterator1 frist1, InputIterator1 last1, InputIterator2 first2, 
        OutputIterator result, double supply, double limit );
};

template<>
struct GetQuantity<0> {
    // specialized stuff
};
于 2013-11-06T15:38:52.920 に答える
2

a を部分的に特殊化する代わりに、オーバーロードstructを使用することができます。std::integral_constant

template<class InputIterator1, class InputIterator2, class OutputIterator>
void GetQuantity(InputIterator1 first1, InputIterator1 last1,
                 InputIterator2 first2, OutputIterator result,
                 double supply, double limit,
                 std::integral_constant<int, 0>);

これは、ディスパッチャーを介して呼び出すことができます。

template<int distribution,
         class InputIterator1, class InputIterator2, class OutputIterator>
void GetQuantity(InputIterator1 first1, InputIterator1 last1,
                 InputIterator2 first2, OutputIterator result,
                 double supply, double limit)
{
    GetQuantity(first1, last1, first2, result, supply, limit,
                std::integral_constant<int,distribution>{});
}

デフォルトの実装は、変換シーケンスを介して提供できます。

template<int dist>
struct der_int_const : std::integral_constant<int, dist>
{}

template<int distribution,
         class InputIterator1, class InputIterator2, class OutputIterator>
void GetQuantity(InputIterator1 first1, InputIterator1 last1,
                 InputIterator2 first2, OutputIterator result,
                 double supply, double limit, der_int_const<distribution>{});

パラメータでも部分的に特殊化する別の方法がありdistributionます(簡略化):

#include <iostream>
#include <type_traits>

struct X0{};
struct X1{};

template<int distribution, class It,
         class U = typename std::enable_if<distribution==0>::type>
void GetQuantity(It, X0={});

template<int distribution, class It,
         class U = typename std::enable_if<(distribution>1)>::type>
void GetQuantity(It, X1={});

C++03 バージョン:

#include <boost/type_traits.hpp>

そして、boost::integral_constant代わりに使用しますstd::integral_constant

#include <boost/utility/enable_if.hpp>

struct X0{};
struct X1{};

template<int distribution, class It>
typename boost::enable_if_c<distribution==0>::type
GetQuantity(It, X0=X0()){ std::cout<<"0\n"; }

template<int distribution, class It>
typename boost::enable_if_c<(distribution>1)>::type
GetQuantity(It, X1=X1()){ std::cout<<"1\n"; }
于 2013-11-06T15:52:11.567 に答える