在默认模板“函数参数”上

On Default template Function Parameter

本文关键字:参数 函数参数 函数 默认      更新时间:2023-10-16

我想设计一组函数,如minmaxstddev,它们可以支持用户定义的类型。我计划让用户将Extractor模板参数传递给这些函数。一些示例代码如下:

template <typename T>
struct DefaultExtractor
{
  typedef T value_type;
  static T value(T &v){
    return v;
  }
};
template <
  typename Extractor=DefaultExtractor<typename std::iterator_traits<InputIterator>::value_type>, //error
  typename InputIterator>
typename Extractor::value_type 
foo(InputIterator first, InputIterator last)
{
  return Extractor::value(*first);
}

这不会编译,并且typename Extractor=...的行上的错误消息为"error:'InputIterator'未在此范围内声明"。

我想把模板Extractor放在InputIterator之前的原因是,当用户想用自定义的Extractor调用foo时,他们不需要显式地提供InputIterator的类型。

我想知道是否有一种解决方案可以编译代码,同时在需要自定义Extractor时,它不需要用户显式提供参数InputIterator

代码是用g++-4.6.1 -std=c++0x编译的。

虽然我看到您希望将提取器作为模板参数传递,但实际上更典型的做法是将对象传递给函数。它也更灵活,因为它允许您拥有可以传递给提取器的额外状态。

最重要的是,它使处理模板参数变得更容易:

#include <iterator>
#include <list>
template <typename T>
struct DefaultExtractor
{
  typedef T value_type;
  static T value(T &v){
    return v;
  }
};
struct MyExtractor {
  typedef int value_type;
  static int value(int value) { return value; }
};
template <typename Extractor, typename InputIterator>
inline typename Extractor::value_type
foo(
  InputIterator first,
  InputIterator last,
  const Extractor &extractor
)
{
  return extractor.value(*first);
}
template <typename InputIterator>
inline typename DefaultExtractor<
  typename std::iterator_traits<InputIterator>::value_type
>::value_type
foo(
  InputIterator first,
  InputIterator last
)
{
  typedef DefaultExtractor<typename std::iterator_traits<InputIterator>::value_type> Extractor;
  return foo(first,last,Extractor());
}

int main(int argc,char **argv)
{
  std::list<int> l;
  // Use default extractor
  foo(l.begin(),l.end());
  // Use custom exractor.
  foo(l.begin(),l.end(),MyExtractor());
  return 0;
}