名称重载的模板化方法

时间:2010-09-29 15:22:24

标签: c++ templates

为了与库中的其他类保持一致,下面的数组类有两个read()方法。第一个读取整个数组到输出迭代器并返回错误代码,第二个读取单个值并返回(使用异常的错误)。

我遇到的问题是,如果我用int调用第二个read(size_t idx)方法,编译器更喜欢模板化方法。我需要显式指定unsigned int以使其工作。我的问题是,我对此问题的选择是什么:

  • 重命名read函数以避免重载
  • 使用boost :: enable_if之类的东西来防止迭代器版本与非迭代器一起使用。这虽然扼杀了界面......
  • 我缺少的任何其他想法?

----------------------------------------------- --------------

#include <iostream>
#include <iterator>
#include <vector>

struct FooArray
{
  template <typename TIter>
  int read( TIter out )
  {    
    *out++ = 123.456; // copy stuff to output iterator
    return 99;        // error code
  }

  double read( size_t index )
  {    
    return 1.234; // return value at index
  }
};

int main(int argc, char**argv)
{
  FooArray tmp;
  std::cout << tmp.read(10u) << std::endl;
  /* std::cout << tmp.read(10) << std::endl;   COMPILER ERROR */
  tmp.read( std::ostream_iterator<double>(std::cout,"\n") ); 
}

1 个答案:

答案 0 :(得分:1)

此外,我不认为size_tunsigned的同义词,因此即使使用“u”后缀,代码也可能无法移植。

std::string有一个类似的问题,它必须区分:

string s(10, 97);  //size_t, char
string t(s.begin(), s.end()); //iter

这会在内部将调用转发给合适的辅助函数(如果参数是完整的,则需要在某处进行编译时测试。)

但是,在您的情况下,返回类型也不同,因此您必须选择正确的重载开始。

使用enable_if

看起来不会那么糟糕
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_integral.hpp>

struct FooArray
{
  template <typename TIter>
  typename boost::disable_if<boost::is_integral<TIter>, int>::type
       read( TIter out )
  {
    *out++ = 123.456; // copy stuff to output iterator
    return 99;        // error code
  }

  double read( size_t index )
  {
    return 1.234; // return value at index
  }
};