Меньше, чем оператор через неявное преобразование?
Рассмотрим следующий класс:
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 не преобразуется вint
s. это ошибка в вашем коде, потому что он не является корректным const. Добавление ключевого словаconst
сделает его работоспособным, и классC
действительно будетLessThanComparable
. Строгое слабое упорядочивающее отношение выполняется, потому чтоint
s выполняют это требование.Если вы исправите свою постоянность, да, это будет.Будет
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; } }