4

fooA()現在、引数として特定のコンテナ、たとえば、を期待する(本文を気にしない)のようなコードで立ち往生してvector<double>います。

double fooA(std::vector<double> const& list)
{
    return list[0];
}

ここで、代わりにイテレータを一般化して使用したいと思います。

template<typename InputIterator>
double fooB(InputIterator first, InputIterator last)
{
    return *first;
}

fooB()イテレータが反復する必要があることをどのように述べるのdoubleですか?

誰かが、vector<string>::iteratorまたは、警告なしにコンパイルされる可能性があるため、さらに悪いことに、を渡す可能性がありますvector<int>::iterator

4

2 に答える 2

4

C ++ 03の場合:

#include <iterator>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/utility/enable_if.hpp>

template<typename InputIterator>
typename boost::enable_if<
    boost::is_same<
        typename boost::remove_cv<
            typename std::iterator_traits<InputIterator>::value_type
        >::type,
        double // expected value_type
    >,
    double     // fooB return type
>::type
fooB(InputIterator first, InputIterator last)
{
    return *first;
}

Boostを使用しない別のC++03ソリュ​​ーションですが、無効な型を渡すと、はるかに醜いエラーが発生する可能性があります。

#include <iterator>

void fooB_helper(double) { }
template<typename T> void fooB_helper(T const&);

template<typename InputIterator>
double fooB(InputIterator first, InputIterator last)
{
    fooB_helper(typename std::iterator_traits<InputIterator>::value_type());
    return *first;
}

C ++ 11の場合、式SFINAEの代わりに使用するenable_ifか、SFINAEの代わりに使用することができstatic_assertます。

于 2012-04-13T17:19:49.220 に答える
0

Boost / C ++ 11を使用したくない場合は、次の方法で解決できる可能性があります。

template<typename B, template<typename A1, typename B1> class Container>
double fooB(typename Container<int, B>::iterator first,
   typename Container<int, B>::iterator last)
{
  return 0;
}

電話する:

vector<int> a;
fooB<vector<int>::allocator_type, vector>(a.begin(), a.end());

少し醜いですが、動作します:)

また、stdコレクションの実装は3つ以上のテンプレートパラメーターを持つことができるため、移植性はありません(2番目のパラメーターはデフォルト値のアロケーターです)

于 2012-04-13T17:19:23.770 に答える