#c
#c
Вопрос:
При создании std::set
одним из параметров шаблона является class Compare
, значение которого по умолчанию равно std::less<T>
.
Теперь, даже если вы не указываете специализацию std::less<T>
, определение T::operator<
достаточно хорошо для C , чтобы «разобраться». Но C ничего не выясняет, компилятор.
И компилятор выполняет ряд, я уверен, простых шагов. Что это за шаги?
Комментарии:
1.
But C isn't figuring anything out, a compiler is.
Справедливости ради, C диктует, что делает компилятор (до некоторой степени. Это определяет границы, которым должен следовать компилятор. В редких случаях это позволяет компилятору выбирать, что делать, но, похоже, это не один из таких случаев).
Ответ №1:
Стандартная библиотека определена таким образом, что std::less<T>
будет использоваться operator<
, если не предусмотрено иное. Итак, если вы не предоставляете специализацию, если тип поддерживает <
, тогда это сработает.
От std::less<T>
:
Объект функции для выполнения сравнений. Если не специализирован, вызывает
operator<
по типуT
.
И для std::less<T>::operator()
:
Возможная реализация :
constexpr bool operator()(const T amp;lhs, const T amp;rhs) const
{
return lhs < rhs;
}
Ответ №2:
Проверьте определяемую компилятором специализацию std::less<void>.
Как вы можете видеть, он просто возвращает результат lhs < rhs.
Что касается того, как компилятор знает, что нужно привязывать std::less<void>
вместо std::less<T>
, это потому, что никакая специализация std::less<T>
не была явно написана. Поэтому, когда вы запрашиваете его, он должен быть сгенерирован автоматически.
Итак, почему компилятор находит std::less<void>
вместо std::less<>
? Это потому, что, когда вы не передаете параметр шаблона, std::less
вы получаете std::less<void>
.
Комментарии:
1.
std::less<T>
определенно «существует», поскольку эта специализация автоматически генерируется, когда вы запрашиваете ее.std::less
просто объявляетсяtemplate<typename T = void> struct less;
, поэтому, если вы запрашиваетеstd::less<>
без указанияT
, вы получаетеT = void
по умолчанию. Единственная магия в том, что еслиT
это тип указателя.2. Я не уверен, почему вы ввели
void
в это.3. Это то, что я понимаю из того, что я только что узнал от Google. Пожалуйста! Я был бы рад, если бы вы дали мне лучший ответ.
4.
std::less<void>
реализация не имеет значения,std::set<T>
по умолчаниюstd::less<T>
5. @AriSweedler Да. Если вы предоставите,
MyClass::operator<
тоstd::less<MyClass>
можете использовать общую реализациюstd::less<T>
, потому что для этой реализации просто требуется, чтобы существовалoperator<
который используетT
. Обратите внимание, что вы также можете предоставить бесплатную функциюbool operator<(const MyClass amp;, const MyClass amp;)
вместо этого, и она также будет работать.