Типы Функтора сравнения по сравнению с оператором <

Я думаю, что значение f становится:

function(n) { console.log("hello"); })
blockquote>

Верно!

Я не уверен, что такое «контекст»? [ 1126] blockquote>

«Контекст» - это слово, которое люди иногда используют (неверно, ИМХО) для ссылки на значение this для вызова функции.

При вызове times:

n.times(function(n) { console.log("hello"); });

... нет аргумента для параметра context, передаваемого в times, поэтому times получит undefined для значение его context параметра. Затем он использует это значение в f.call(...). Когда вы используете undefined (или null) с Function.prototype.call, в свободном режиме функция вызывается с this, установленным в глобальный объект; в строгом режиме функция видит this ase undefined или null вместо этого.

Таким образом, в этом примере обратный вызов будет вызываться либо с глобальным объектом как this, либо undefined как this.

Это аналог параметра thisArg в Array.prototype.forEach и связанных с ним.

10
задан Adam Bellaire 8 October 2008 в 16:24
поделиться

7 ответов

За исключением более фундаментальных типов, меньше операция не всегда тривиальна, и даже равенство может варьироваться от ситуации до ситуации.

Вообразите ситуацию авиакомпании, которая хочет присвоить всем пассажирам номер обшивки. Это число отражает порядок обшивки (конечно). Теперь, что определяет, кто приезжает прежде кто? Вы могли бы просто взять порядок, в котором зарегистрированные клиенты – в этом случае, меньше операция сравнит времена регистрации. Вы могли бы также полагать, что ценовые клиенты, оплаченные их билеты – меньше, теперь сравнят цены на билеты.

… и так далее. В целом, это просто не значимо для определения operator < на Passenger класс, хотя это может потребоваться, чтобы иметь пассажиров в отсортированном контейнере. Я думаю, что это - то, от чего предостерегает Google.

16
ответ дан 3 December 2019 в 14:12
поделиться

Обычно определение operator< лучше и более прост.

Случай, где Вы хотели бы использовать функторы, - при необходимости в нескольких способах сравнить конкретный тип. Например:

class Person;

struct CompareByHeight {
    bool operator()(const Person &a, const Person &b);
};

struct CompareByWeight {
    bool operator()(const Person &a, const Person &b);
};

В этом случае не может быть хорошего способа "по умолчанию" сравнить и заказать людям так не определение operator< и использование функторов может быть лучше. Вы могли также сказать, что обычно людям приказывает высота, и таким образом, operator< просто вызовы CompareByHeight, и любой, кому нужен Человек, чтобы быть заказанным в развес, должен использовать CompareByWeight явно.

Часто времена, которыми проблема состоит в том, что определение функторов оставляют до пользователя класса, так, чтобы Вы были склонны получать много переопределений того же самого, каждый раз, когда класс должен использоваться в заказанном контейнере.

6
ответ дан 3 December 2019 в 14:12
поделиться

Ну, согласно веб-странице Вы цитируете, нет большого преимущества для функторов (" [операторы], может дурачить нашу интуицию, заставляя думать, что дорогие операции являются дешевыми, встроенными операциями. ")

Мой лесоповал - то, что нужно стремиться сделать Вас, классы в первом классе возражают как можно больше, который, мне, означает иметь их, понимают столько же операторов сколько разумный.

Это было некоторое время так как я записано функтор, но это выглядело бы примерно так:

class MyClass {....}

class LessThanMyClass : std:binary_function<MyClass, MyClass, bool>
{
    public bool operator()(MyClass lhs, MyClass rhs) 
    {   return /* determine if lhs < rhs */ ; }
}

vector<MyClass> objs;
std::sort(objs.begin(), objs.end(), LessThanMyClass());

}

5
ответ дан 3 December 2019 в 14:12
поделиться

Я думаю, что сообщение позади не определения оператора <-то, что упорядочивание является свойством набора, не объекта. Различные наборы тех же объектов могут иметь различные упорядочивания. Таким образом, необходимо использовать отдельный функтор, используемый при определении типа набора, а не оператора <.

На практике, хотя, много Ваших классов может иметь естественное упорядочивание, и это - единственное упорядочивание, используемое в наборах в Вашем приложении. В других случаях упорядочивание даже не может относиться к приложению, просто набор, таким образом, это может найти объекты позже. В этих случаях имеет смысл определять оператор <.

Помните, когда мы - desiging объектные модели, мы только моделируем подмножество реального мира. В реальном мире могут быть многочисленные различные способы оценить объекты того же класса, но в домене приложения, в котором мы работаем, может быть тот, который релевантен.

Если код развивается для необходимости во втором упорядочивании, которое столь же релевантно как первое, класс должен быть пересмотрен, чтобы удалить оператор <и поместить обе занимающих место функции в отдельные функторы. Это показывает намерение, что никакой рейтинг не более важен, чем другие.

Относительно арифметических операторов Вы не должны перегружать их, если Вы не реализуете арифметический тип.

Конечно, существуют исключения к каждому правилу. Если Вы не знаете, необходимо ли делать исключение, Вы, вероятно, не должны. Опыт будет Вашим руководством.

3
ответ дан 3 December 2019 в 14:12
поделиться

Я, вероятно, не пошел бы до руководства по стилю Google.

Я думаю, что то, что они достигают, является этим, когда Вы перегружаетесь operator< и operator==, Вы принимаете решение для каждого использования типа, в то время как функтор вводит, только относятся к тому набору.

Если единственная вещь, для которой Вы нуждаетесь в компараторах, состоит в том, чтобы поместить объект в набор, то лучше иметь функционально-специализировано для того контекста, а не операторов, которые применялись бы во всех контекстах.

Можно хотеть отсортировать заказы на покупку хронологически, но в целом, имело бы смысл сравнивать их их общей стоимостью. Если мы перегружаемся operator< для сравнения дат так, чтобы мы могли загрузить их в набор мы представляем риск, что другой клиент может неправильно использовать наш operator< то, которое они могут думать, сравнивает общие стоимости.

3
ответ дан 3 December 2019 в 14:12
поделиться

Функтор является классом с operator (). В этом случае метод взял бы два параметра сравниваемого типа и возвратил бы a bool закончитесь, если первыми являются меньше, чем второе.

Править: для построения, что сказал James Curran можно определить функтор в классе. Так, например:

class MyClass
{
    struct LessThan : public std::binary_function<MyClass, MyClass, bool>
    {
        bool operator()(const MyClass & first, const MyClass & second) const
        {
            return first.key < second.key;
        }
    };
};
2
ответ дан 3 December 2019 в 14:12
поделиться

Как ни странно, функтор также требует переопределения оператора (оператор вызова функции - operator ()), таким образом, я не уверен, какова их точка.

1
ответ дан 3 December 2019 в 14:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: