1 Востаннє редагувалося Yola (07.04.2017 08:43:03)

Тема: Так працює, а так ні. Оператор порівняння для шаблонного класу.

Так працює:

template <class ED>
struct EdgeData {
    EdgeData(int indexTo, const ED& edgeData) : indexTo(indexTo), edgeData(edgeData) {}
    EdgeData(int indexTo, ED&& edgeData) : indexTo(indexTo), edgeData(move(edgeData)) {}
    int indexTo;
    ED edgeData;
};
template <class ED>
bool operator<(const EdgeData<ED>& l, const EdgeData<ED>& r) { return l.indexTo < r.indexTo; }

а так ні:

template <class ED>
struct EdgeData {
    EdgeData(int indexTo, const ED& edgeData) : indexTo(indexTo), edgeData(edgeData) {}
    EdgeData(int indexTo, ED&& edgeData) : indexTo(indexTo), edgeData(move(edgeData)) {}
    bool operator<(const EdgeData<ED>& other) { return indexTo < other.indexTo; }
    int indexTo;
    ED edgeData;
};

Помилка - страшне багатошарове повідомлення через використання std::is_sorted

2

Re: Так працює, а так ні. Оператор порівняння для шаблонного класу.

У мене обидва варіанти компілюються.
Додайте назву компілятора, особливі опції компіляції, повний текст помилки і спробуйте знайти той рядок, який насправді породжує цю помилку (де ви використовуєте цей оператор).

3 Востаннє редагувалося Yola (07.04.2017 13:28:09)

Re: Так працює, а так ні. Оператор порівняння для шаблонного класу.

А так:

#include <vector>
#include <algorithm>

template <class ED>
struct EdgeData1 {
    bool operator<(const EdgeData1<ED>& other) { return indexTo < other.indexTo; }
    int indexTo;
    ED edgeData;
};

template <class ED>
struct EdgeData2 {
    int indexTo;
    ED edgeData;
};
template <class ED>
bool operator<(const EdgeData2<ED>& l, const EdgeData2<ED>& r) { return l.indexTo < r.indexTo; }

std::vector<EdgeData1<int>> v1;
std::vector<EdgeData2<int>> v2;

void main() {
    std::is_sorted(cbegin(v1), cend(v1));
    std::is_sorted(cbegin(v2), cend(v2));
}

Трошки зменшив код, щоб не доводилось прокручувати.

4

Re: Так працює, а так ні. Оператор порівняння для шаблонного класу.

Ось помилка:

In file included from /usr/include/c++/6/bits/stl_algobase.h:71:0,
                 from /usr/include/c++/6/vector:60,
                 from prog.cpp:1:
/usr/include/c++/6/bits/predefined_ops.h: In instantiation of ‘constexpr bool __gnu_cxx::__ops::_Iter_less_iter::operator()(_Iterator1, _Iterator2) const [with _Iterator1 = __gnu_cxx::__normal_iterator<const EdgeData1<int>*, std::vector<EdgeData1<int> > >; _Iterator2 = __gnu_cxx::__normal_iterator<const EdgeData1<int>*, std::vector<EdgeData1<int> > >]’:
/usr/include/c++/6/bits/stl_algo.h:3234:12:   required from ‘_ForwardIterator std::__is_sorted_until(_ForwardIterator, _ForwardIterator, _Compare) [with _ForwardIterator = __gnu_cxx::__normal_iterator<const EdgeData1<int>*, std::vector<EdgeData1<int> > >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]’
/usr/include/c++/6/bits/stl_algo.h:3258:36:   required from ‘_FIter std::is_sorted_until(_FIter, _FIter) [with _FIter = __gnu_cxx::__normal_iterator<const EdgeData1<int>*, std::vector<EdgeData1<int> > >]’
/usr/include/c++/6/bits/stl_algo.h:3207:34:   required from ‘bool std::is_sorted(_FIter, _FIter) [with _FIter = __gnu_cxx::__normal_iterator<const EdgeData1<int>*, std::vector<EdgeData1<int> > >]’
prog.cpp:23:44:   required from here
/usr/include/c++/6/bits/predefined_ops.h:43:23: error: no match for ‘operator<’ (operand types are ‘const EdgeData1<int>’ and ‘const EdgeData1<int>’)
       { return *__it1 < *__it2; }
                ~~~~~~~^~~~~~~~
prog.cpp:6:14: note: candidate: bool EdgeData1<ED>::operator<(const EdgeData1<ED>&) [with ED = int] <near match>
         bool operator< (const EdgeData1<ED>& other)  { return indexTo < other.indexTo; }
              ^~~~~~~~
prog.cpp:6:14: note:   passing ‘const EdgeData1<int>*’ as ‘this’ argument discards qualifiers

Основне тут - в останньому рядку: передача const EdgeData1<int>* як аргументу this скидає специфікатор. Тобто this має бути константним, а в операторі він не константний. Виправляємо:

-    bool operator<(const EdgeData1<ED>& other) { return indexTo < other.indexTo; }
+    bool operator<(const EdgeData1<ED>& other) const { return indexTo < other.indexTo; }

Все гаразд.

Подякували: Yola1

5

Re: Так працює, а так ні. Оператор порівняння для шаблонного класу.

Оце я неуважний! Там const тре!

Подякували: koala1

6

Re: Так працює, а так ні. Оператор порівняння для шаблонного класу.

Бачите, не ви один неуважний. Для цього компілятори і виводять повідомлення про помилки, їх тільки треба читати :)

Подякували: Yola1