Меньше, чем оператор через неявное преобразование?
Рассмотрим следующий класс:
struct C
{
/* Class contents, without any arithmetic operator... */
constexpr operator int() noexcept; // Implicit conversion to int
};
Мой вопрос:
- можно ли использовать C в стандартных алгоритмах, таких как
std::sort, которые в настоящее время используют оператор - считается, что C удовлетворяет
LessThanComparableконцепция? - будет соответствовать требованиям гипотетической концептуальной библиотеки алгоритмов, которая требует, чтобы тип был
LessThanComparable.
3 ответа:
Да, он работает дляЯвляется
Cпригодным для использования в стандартных алгоритмах, таких какstd::sort, которые в настоящее время используют оператор по умолчанию<?std::sort()и некоторых других стандартных алгоритмов. Код#include <algorithm> #include <vector> struct C { /* Class contents, without any arithmetic operator... */ constexpr operator int() noexcept {return 0;} // Implicit conversion to int }; int main() { std::vector<C> v; std::sort( begin(v), end(v) ); }Компилирует. вот живая демонстрация. посмотри хоть на следующий вопрос!
Считается ли
Cудовлетворяющим понятиюLessThanComparable?Нет. Требования концепции
LessThanComparableтаковы, что для объектовxиyтипаCили Выражениеconst Cсправедливо и неявно преобразуется в bool, а оператор<устанавливает строгое слабое отношение упорядочения. В вашем случае const objects do не преобразуется вints. это ошибка в вашем коде, потому что он не является корректным const. Добавление ключевого словаconstсделает его работоспособным, и классCдействительно будетLessThanComparable. Строгое слабое упорядочивающее отношение выполняется, потому чтоints выполняют это требование.Если вы исправите свою постоянность, да, это будет.Будет
Cотвечать требованиям гипотетический концептуализированный алгоритм библиотека, для которой требуется ТипLessThanComparable.Несколько примечаний:
GCC 4.9 компилирует
x<y, даже еслиxиyимеют типconst C. Это похоже на ошибку компилятора, так как GCC 5.2 и clang 3.6 выбрасывают ошибку времени компиляции здесь.Передача
std::less<C>()в качестве дополнительного аргумента вstd::sort()приводит к ошибке компиляции, поскольку функция сравнения требует, чтобы постоянные объекты были сопоставимы в этом случае. Однако передачаstd::less<void>()ничего не нарушает, так как аргументы прекрасно передаются.Тот самый
std::sort()алгоритм требует не полногоLessThanComparable, а понятияCompare. Кроме того, тип итератора должен бытьRandomAccessIterator, то естьValueSwappable, а разыменованный тип должен бытьMoveContructableиMoveAssignable. Это все относится к вашему первому вопросу, даже если ошибка constness не исправлена. Вот почемуstd::sort()и другие стандартные алгоритмы работают.
Нет. Компилятор не может сделать такую большую магию, то есть вызвать метод cast и затем применить оператор
<. Представьте, что существует несколько операторов приведения для разных типов, как компилятор выберет правильный?EDIT: на самом деле это не так. Пока есть один оператор приведения, это будет работать. Но с двумя или более компилятор будет жаловаться на неоднозначное приведение. Однако этот подход очень хрупок, так что в целом это не очень хорошая идея.
Я попробовал пример, предложенный mehrdad momeny. Это сработало отлично. Однако при небольшом редактировании он больше не работает.
Потому что это приведет к двусмысленности. Так что, это не очень хорошая идея, чтобы сделать это так.#include <iostream> #include <string> #include <vector> #include <algorithm> struct C { C(int x):X(x){} operator int() { return X; } operator float() { return static_cast<float>(X); } int X; }; using namespace std; int main() { vector<C> u = {1, 2, 35, 6, 3, 7, 8, 9, 10}; sort(u.begin(), u.end()); for(auto x: u){ cout << x << endl; } }