Меньше чем оператор через неявное преобразование?

Рассмотрим следующий класс:

struct C
{
/* Class contents, without any arithmetic operator... */
constexpr operator int() noexcept; // Implicit conversion to int
};

Мой вопрос:

  • Можно ли использовать C в стандартных алгоритмах, таких как std::sort который в настоящее время использует по умолчанию < оператор?
  • С считается ли удовлетворяющим LessThanComparable концепция?
  • Будет ли C соответствовать требованиям библиотеки гипотетических концептуализированных алгоритмов, которая требует, чтобы тип был LessThanComparable,

16

Решение

Является 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 выражение x<y является действительным и неявно конвертируемым в bool и < Оператор устанавливает строгое отношение слабого порядка. В вашем случае объекты const не будут преобразованы в ints. Это ошибка в вашем коде, потому что она не является правильной. Добавление const Ключевое слово заставит его работать и класс C действительно будет LessThanComparable, Строгое слабое отношение порядка выполняется, потому что ints выполнить это требование.

Будет C соответствовать требованиям гипотетического концептуализированного алгоритма
библиотека, которая требует, чтобы тип был LessThanComparable,

Если вы исправите свое постоянство, да, это будет.

Несколько sidenotes:

  • 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, Это все относится к вашему первому вопросу, даже если ошибка константности не исправлена. Вот почему std::sort() и другие стандартные алгоритмы работают.

12

Другие решения

Нет. Компилятор не может сделать такую ​​большую магию, то есть вызвать метод cast и затем применить < оператор. Представьте, что есть несколько операторов приведения для разных типов, как бы компилятор выбрал правильный?

РЕДАКТИРОВАТЬ: На самом деле это не правильно. Пока есть один оператор приведения, это будет работать. Но с двумя или более компилятор будет жаловаться на неоднозначное приведение. Тем не менее, этот подход очень хрупкий, так что в целом это не очень хорошая идея.

3

Я попробовал пример, предложенный Мердад Момены. Работало нормально. Однако, с небольшим редактированием, это больше не работает.

#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;
}
}

Live Demo

Потому что это приведет к двусмысленности. Так что не стоит делать это так.

2
По вопросам рекламы ammmcru@yandex.ru