#c #c 17
#c #c 17
Вопрос:
Я пишу метод сортировки, который сортирует два массива одновременно на основе значений в одном из массивов. Я использовал это в качестве ссылки и внес несколько незначительных изменений (сделал operator*()
const и добавил конструкторы для класса ref
), поэтому он компилируется в MSVC / g / clang.
После добавления std::execution::par
, чтобы включить параллельную сортировку, clang и g больше не компилируют ее (но MSVC это делает). Окончательный код и ошибку можно найти здесь . Ошибки в g и clang похожи:
источник:45:6: примечание: функция-кандидат нежизнеспособна: нет известного преобразования из ‘const val’ в ‘const ref’ для 1-го аргумента bool operator<(ref const amp; a, val const amp; b)
Эта ошибка может быть устранена путем реализации bool operator<(val constamp; a, val constamp; b)
, но тогда массив конечных значений содержит пустые строки. Это можно решить, удалив move
оператор from operator val() amp;amp;
. Однако move
оператор был важным дизайнерским решением для повышения производительности.
Вопрос: Есть ли способ сохранить оператор перемещения?
Итак, теперь он компилируется в онлайн-среде godbolt.org , но не локально, поскольку установка tbb влияет на этапы компиляции. Tbb устанавливается локально и необходим для фактического параллельного выполнения. Ошибка:
/usr/include/c /9/pstl/parallel_backend_tbb.h:435:1: required from here
/usr/include/c /9/bits/predefined_ops.h:215:11: error: no match for call to ‘(std::less<val>) (const refamp;, ref)’
215 | { return bool(_M_comp(__val, *__it)); }
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c /9/string:48,
from tmp.cpp:2:
/usr/include/c /9/bits/stl_function.h:385:7: note: candidate: ‘constexpr bool std::less<_Tp>::operator()(const _Tpamp;, const _Tpamp;) const [with _Tp = val]’ <near match>
385 | operator()(const _Tpamp; __x, const _Tpamp; __y) const
| ^~~~~~~~
/usr/include/c /9/bits/stl_function.h:385:7: note: conversion of argument 1 would be ill-formed:
In file included from /usr/include/c /9/bits/stl_algobase.h:71,
from /usr/include/c /9/vector:60,
from tmp.cpp:1:
/usr/include/c /9/bits/predefined_ops.h:215:11: error: invalid user-defined conversion from ‘const ref’ to ‘const valamp;’ [-fpermissive]
215 | { return bool(_M_comp(__val, *__it)); }
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
tmp.cpp:42:2: note: candidate is: ‘ref::operator val() amp;amp;’ <near match>
42 | operator val() amp;amp; { return {*key, *value}; }
| ^~~~~~~~
tmp.cpp:42:2: note: passing ‘const ref’ as ‘this’ argument discards qualifiers
Дополнительный вопрос: почему он хочет выполнить преобразование, если он может использовать bool operator<(ref constamp; a, ref constamp; b)
?
Комментарии:
1.
zip_iterator
может вас заинтересовать (как boost )2. Сверху,
sort_it
не соответствует требованиям итератора, и поэтому передача егоstd::sort
показывает неопределенное поведение. » [forward.iterators]/1 Тип класса или указателяX
удовлетворяет требованиям прямого итератора, если … еслиX
является изменяемым итератором,reference
является ссылкой наT
; еслиX
является постоянным итератором,reference
является ссылкой наconst T
» (гдеT
естьvalue_type
).3. @Jarod42 спасибо, что указали мне направление zip_operator . Я нашел интересное обсуждение stackexchange .