std :: pair с сопоставимым и несопоставимым объектом должен быть отсортирован - PullRequest
0 голосов
/ 27 июня 2018

Я столкнулся со следующей проблемой. У меня есть std::vector< std::pair<int, Move> > x типа std::pair<int, Move>, где Move - произвольный объект, для которого не определен оператор сравнения, например, < > !+ == <= >= и т. Д.

Основная причина, по которой я связал объекты Move с целочисленными значениями, заключается в том, что у объектов Move должен быть номер, описывающий их приоритет для какой-либо цели. Основное намерение состоит в сортировке вектора, таким образом сортируя Move объектов, используя их соответствующие целочисленные значения.

Реальная проблема начинается, когда я хочу отсортировать эти пары в векторе, используя функцию std::sort. Сначала я думал, что для сравнения важен только первый элемент std::pair, однако оказалось, что для успешной компиляции программы обоим объектам необходимы определенные для них операции сравнения.

Поскольку я не хотел изменять исходный класс Move, я написал класс Wrapper, который должен был обернуть std::pair<int, Move>, и в нем была определена операция сравнения, чтобы можно было отсортировать std::vector< Wrapper < std::pair<int, Move> > > x; без необходимости изменить Move класс. Логика здесь в том, что vector предоставляется класс, для которого определена операция <.

Я использовал следующий класс оболочки:

template <typename T>
struct Wrapper{
    Wrapper(const T & pair): pair_mem(pair)
    bool operator(const T & other_pair) const{
          return this->pair_mem.first < other_pair.first;
    }
    T pair_mem;
};

Ну, как вы уже догадались, вышеприведенный подход не сработал, и мне пришлось пройти через кучу ошибок компилятора. Наконец, я попытался добавить < operator в класс Move и даже после этого мне не удалось скомпилировать программу.

Ниже приведена ошибка, которую я считаю наиболее важной.

: note: this candidate was rejected because mismatch in count of arguments
    struct Wraper{
           ^
: note: this candidate was rejected because mismatch in count of arguments
            Wraper(const std::pair<int, Move> & move){

Я использую mpiCC в качестве компилятора

UPDATE

Я изменил T на Wrapper, как один из предложенных ответов, но проблема не решена. Вот скриншот от компилятора,

enter image description here

Ответы [ 3 ]

0 голосов
/ 27 июня 2018

Ваш класс оболочки должен быть похож на:

template <typename T>
struct Wrapper{
    Wrapper(const T & pair): pair_mem(pair) {}
    bool operator <(const Wrapper& rhs) const {
        return pair_mem.first < rhs.pair_mem.first;
    }
    T pair_mem;
};

Демо

Но использование пользовательского компаратора кажется лучше (менее навязчивым).

std::sort(x.begin(), x.end(),
          [](const auto& lhs, const auto& rhs) {
              return lhs.first < rhs.first;
          });
0 голосов
/ 27 июня 2018

Когда компилятор выдает ошибки, не пропускает первое сообщение . Из вашего изображения (вы действительно должны были скопировать текст вместо создания изображения):

ошибка: ни один экземпляр конструктора Wraper<T>::Wraper не соответствует списку аргументов vector(size_type __n, const value_type& __value = value_type()

С ошибкой, указанной (с помощью каретки на следующей строке) как возникающей на value_type(). Сообщения, которые вы добавили в свой вопрос, являются не ошибками, а объяснением того, что компилятор пытался сделать, чтобы найти отсутствующий конструктор. Они перечисляют struct, который был опробован для value_type, и найденный конструктор, который принимает параметр T. Это не соответствует, потому что компилятор ищет конструктор по умолчанию (без параметров).

Предположительно, в строке 137 search-abid_parallel.cpp вы объявляете вектор вашего класса-обертки, используя конструктор, который задает начальный размер вектора. (Кроме того, основываясь на сообщении об ошибке, pre-C ++ 11?) Этот конструктор должен иметь возможность конструировать эти начальные элементы по умолчанию. Конструктор по умолчанию был подавлен, когда вы определили другой конструктор, следовательно, ошибка.

Некоторые опции:

  1. По умолчанию инициализировать вектор, затем вызвать reserve(), если вы хотите избежать перераспределения при построении вектора.

  2. Определите конструктор по умолчанию для вашего класса-оболочки.

  3. Не используйте класс-оболочку. Вместо этого присвойте функцию сравнения std::sort (третий параметр, если не используется политика выполнения C ++ 20).

  4. Не используйте вектор. A std::multimap будет хранить ваши пары и сортировать их для вас.

0 голосов
/ 27 июня 2018

Если вы используете компилятор c ++ достаточно недавно, вы можете использовать лямбду:

std::sort(std::begin(x), std::end(x), [](auto & l, auto & r) {return l.first < r.first; });
...