Iteratorテンプレートパラメータをそのパラメータで特殊化することは可能value_type
ですか?
次のプロトタイプの関数があります。
template<typename InputIterator>
void f(InputIterator first, InputIterator last);
InputIterator::value_type
そして、もしそうなら特別に扱いたいSomeSpecificType.
Iteratorテンプレートパラメータをそのパラメータで特殊化することは可能value_type
ですか?
次のプロトタイプの関数があります。
template<typename InputIterator>
void f(InputIterator first, InputIterator last);
InputIterator::value_type
そして、もしそうなら特別に扱いたいSomeSpecificType.
いくつかの中間構造体を使用して、必要な部分的なテンプレートの特殊化を取得できます。このような何かがトリックを行う必要があります
template<typename T, typename V>
struct f_impl
{
static void f( T first, T last ) {...}; //Default version
};
template<typename T>
struct f_impl<T, SomeSpecificType>
{
static void f(T first,T last) {...}; //Specialisation
};
template<typename InputIterator> void f(InputIterator first, InputIterator last)
{
f_impl<
InputIterator,
typename std::iterator_traits<InputIterator>::value_type
>::f(first,last);
};
SFINAEを使用してenable_if[_c]
、とis_same
がBoostまたは(およびいずれかまたはそれぞれ<type_traits>
で適切に修飾されている)のいずれかであると想定します。boost::
std::
template<typename InputIterator>
typename enable_if<
!is_same<
typename std::iterator_traits<InputIterator>::value_type,
SomeSpecificType
>::value
>::type
f(InputIterator first, InputIterator last)
{
// Default implementation.
}
template<typename InputIterator>
typename enable_if<
is_same<
typename std::iterator_traits<InputIterator>::value_type,
SomeSpecificType
>::value
>::type
f(InputIterator first, InputIterator last)
{
// Special case
}
ブーストの場合はboost::enable_if_c
、上記のようなものに使用してください。あなたは使用boost::enable_if
して取り除くことができます::value
が、それからまた例えばを使用しなければなりませんboost::disable_if
。
どうですか:
template<typename T>
typename std::enable_if<std::is_same<typename T::value_type, SomeType>::value, void>::type
f(T first, T second);
これは機能します。このタイプの特殊化は構造体でのみ機能するため、関数でこれを行うことはできません。
template <typename InputIterator, typename ValueType = typename InputIterator::value_type>
struct foobar
{
static void invoke(InputIterator first, InputIterator second)
{
// ...
}
};
template <typename InputIterator>
struct foobar<InputIterator, SomeSpecificType>
{
static void invoke(InputIterator first, InputIterator second)
{
// ...
}
};
タイプを設定する必要はありません。自動的に推測されます。
私をナイーブと呼んでください、しかしなぜ次のもので十分ではないのですか?
struct MyType; // the only type I want
#include <iterator>
typedef std::iterator<std::input_iterator_tag, MyType> MyIt;
void f(const MyIt & begin, const MyIt & end)
{
/* ... */
}
OK、上記のことを忘れてください、それはナンセンスでした。これを行う方法は次のとおりです。これは、C++0xに対するLucの上記の正解です。
#include <vector>
#include <iterator>
#include <type_traits>
// "int" is our desired iterator value type, "void" is f's return type.
template <typename It>
typename std::enable_if<std::is_same<int, typename std::iterator_traits<It>::value_type>::value, void>::type
f(const It & begin, const It & end) { /* your function here */ }
int main()
{
std::vector<double> x;
std::vector<int> y;
//f(x.cbegin(), x.cend()); // error
f(y.cbegin(), y.cend()); // works
}