Шаблонный метод с перегруженным именем - PullRequest
0 голосов
/ 29 сентября 2010

Чтобы соответствовать другим классам в библиотеке, мой класс массива ниже имеет два метода read ().Первый читает весь массив в выходной итератор и возвращает код ошибки, второй читает одно значение и возвращает его (используя исключения для ошибок).

У меня проблема в том, что если я вызываю второй метод read (size_t idx) с int, компилятор предпочитает шаблонный метод.Мне нужно явно указать unsigned int, чтобы он работал.У меня вопрос, какие у меня есть варианты решения этой проблемы:

  • Переименуйте любую функцию чтения, чтобы избежать перегрузки
  • Используйте что-то вроде boost :: enable_if, чтобы версия итератора не работала-iterators.Это портит интерфейс, хотя ...
  • Любые другие идеи, которые мне не хватает?

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

#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 Ответ

1 голос
/ 29 сентября 2010

Более того, я не думаю, что size_t гарантированно является синонимом для unsigned, поэтому даже с суффиксом "u" код может быть не переносимым.аналогичная проблема, которую нужно различать:

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
  }
};
все будет выглядеть не так плохо
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...