Страницы

Поиск по вопросам

воскресенье, 2 февраля 2020 г.

Функция сортировки, которая принимает методы в качестве аргумента

#cpp #алгоритм


Необходимо отсортировать контейнеры STL, используя разные методы доступа в качестве
аргумента. 

template
T& getFromVectorBySquareBrackets(std::vector& vector, int index)
{
  return vector[index];
}

template
T& getFromVectorByMethodAt(std::vector& vector, int index)
{
  return vector.at(index);
}

template 
typename T::value_type& getFromContainerByIterator(T& container, int index)
{
  typename T::iterator it = container.begin();
  while(index > 0)
  {
    it++;
    index--;
  }
  return *it;
}


Я написал функцию сортировки и хочу передать в качестве параметра методы доступа
написаные выше в функцию ниже:

template
void sort(T container, typename T::value_type& get(T container, int index),const char c)
{
  for(int i = 0; i < container.size(); i++)
  {
    for(int j = i+1; j < container.size()-1; j++)
    {
      if(c == 'a')
      {
        if(get(container, j) < get(container, i))
        {
          std::swap(get(container, j), get(container, i));
        }
      }
    }
  }
}


Но компилятор выдает ошибки в main():

int main{
 //something
 std::vector vector = {//something};
 sort(vector, getFromVectorBySquareBrackets, 'a'); //Errors //Ошибки
 return 0;
}


Получаю:


  no instance of function template "sort" matches the argument list --
  argument types are: (std::vector>,
  unknown-type, char)


и:


  cannot determine which instance of function template
  "getFromVectorBySquareBrackets" is intended


Также я пробовал использовать указатель на функцию (get*)(container, i), Но ничего
не меняется. Имеются ли какие-либо мысли у Вас?
    


Ответы

Ответ 1



В шаблоне функции sort вы объявили обычный параметр get как typename T::value_type& get(T container, int index) Т.е. это функция1, чей первый параметр имеет тип T. Если рассмотреть вызов в вашем примере sort(vector, getFromVectorBySquareBrackets, 'a'); то компилятор выполнит дедукцию шаблонного параметра T как std::vector, в результате чего параметр get получит тип int &get(std::vector, int) Эта функция принимает параметр типа std::vector по значению. Однако ваш шаблон getFromVectorBySquareBrackets объявлен как template T& getFromVectorBySquareBrackets(std::vector& vector, int index) { return vector[index]; } Он принимает свой первый параметр по ссылке. Это уже является непреодолимым противоречием. Невозможно передать такую getFromVectorBySquareBrackets в качестве аргумента для параметра get: как ни специализируй шаблон getFromVectorBySquareBrackets, тип результата не будет соответствовать типу параметра get. Это именно то, на что жалуется компилятор. Если вы измените свое объявлении шаблона sort на template void sort(T container, typename T::value_type& get(T& container, int index), const char c) то вышеописанная проблема будет устранена (при условии, что вы исправите и остальные очевидные синтаксические ошибки в вашем коде). Альтернативно, если вы исправите объявление getFromVectorBySquareBrackets на template T& getFromVectorBySquareBrackets(std::vector vector, int index) ошибка тоже исчезнет, хотя это скорее всего не совсем то, что вы хотели сделать. 1 В списках параметров тип "функция" автоматически заменяется на тип "указатель на функцию", но в данном случае это к делу не относится.

Комментариев нет:

Отправить комментарий