是否可以通过它来专门化一个迭代器模板参数value_type
?
我有一个具有以下原型的功能。
template<typename InputIterator>
void f(InputIterator first, InputIterator last);
如果InputIterator::value_type
是,我想特别处理SomeSpecificType.
是否可以通过它来专门化一个迭代器模板参数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 情况下,boost::enable_if_c
用于与上述类似的东西。您可以使用boost::enable_if
和摆脱,::value
但也必须使用 eg 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)
{
/* ... */
}
好吧,忘记上面的,那是胡说八道。对于 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
}