16

是否可以通过它来专门化一个迭代器模板参数value_type

我有一个具有以下原型的功能。

template<typename InputIterator>
void f(InputIterator first, InputIterator last);

如果InputIterator::value_type是,我想特别处理SomeSpecificType.

4

5 回答 5

10

您可以使用一些中间结构来获得所需的部分模板特化。像这样的东西应该可以解决问题

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);
};
于 2011-06-08T03:20:36.130 回答
8

使用 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

于 2011-06-08T03:25:04.450 回答
0

怎么样:

template<typename T>
typename std::enable_if<std::is_same<typename T::value_type, SomeType>::value, void>::type
f(T first, T second);
于 2011-06-08T03:20:52.827 回答
0

这将起作用。这种类型的专业化只适用于结构,所以我不能用函数来做到这一点。

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)
    {
        // ...
    }
};

这不应该要求您设置类型。它应该是自动推断的。

于 2011-06-08T03:26:27.483 回答
0

称我天真,但为什么以下内容还不够?

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
}
于 2011-06-08T03:39:30.153 回答