ошибка C2039: 'bind2nd': не является членом 'std' [duplicate]

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

10
задан TemplateRex 23 September 2015 в 12:16
поделиться

3 ответа

В C ++ 11 вы можете использовать std::bind; это просто не так очевидно, как его использовать:

#include <functional>
using namespace std::placeholders;
std::find_if(
    foo.begin(),
    foo.end(),
    // create a unary function object that invokes greater<int>::operator()
    // with the single parameter passed as the first argument and `bar` 
    // passed as the second argument
    std::bind(std::greater<int>(), _1, bar)
) - foo().begin() - 1;

Ключом является использование аргумента-заполнителя, объявленного в пространстве имен std::placeholders. std::bind возвращает объект функции, который принимает некоторое количество параметров при его вызове. Заполнители, используемые внутри вызова std::bind, показывают, как аргументы, предоставляемые при вызове результирующего объекта, сопоставляются с списком аргументов вызываемому, к которому вы привязываетесь. Так, например:

auto op1 = std::bind(std::greater<int>(), _1, bar);
op1(5); // equivalent to std::greater<int>()(5, bar)

auto op2 = std::bind(std::greater<int>(), bar, _1);
op2(5); // equivalent to std::greater<int>()(bar, 5)

auto op3 = std::bind(std::greater<int>(), _2, _1);
op3(5, bar); // equivalent to std::greater<int>()(bar, 5)

auto op4 = std::bind(std::greater<int>(), _1, _2);
op4(5, bar); // equivalent to std::greater<int>()(5, bar)
11
ответ дан Jason R 19 August 2018 в 11:53
поделиться
Версия

bind будет:

bind(std::greater<int>(), placeholders::_1, bar)

, но я думаю, что более рекомендуется использовать лямбда, как в:

[bar](const int a){return bar < a;}

Также рекомендуется используйте перегруженные функции begin/end вместо вызовов методов. так это было бы так:

find_if(begin(foo), end(foo), [bar](const int a){return bar < a;})
5
ответ дан behzad.nouri 19 August 2018 в 11:53
поделиться

Как насчет перехода от каменного века (bind2nd) к железному веку с генераторной лямбдой C ++ 14, минуя бронзовый век (bind)?

std::find_if(foo.begin(), foo.end(), [&](auto const& elem) { 
    return elem > bar; 
}); 

И если вход сортируется

std::lower_bound(foo.begin(), foo.end(), bar); 

Lambdas читается намного проще, а также проще встраивать, чем std::bind выражения. См. Обсуждение Lavevej's CppCon 2015 .

9
ответ дан TemplateRex 19 August 2018 в 11:53
поделиться
  • 1
    Я согласен с тем, что это, вероятно, самое легкое для чтения решение, но теги вопроса включают только C ++ 11. – Jason R 23 September 2015 в 12:55
  • 2
    @JasonR моя философия заключается в том, чтобы показать, как я буду ее кодировать, если они не утверждают, что они действительно не могут использовать C ++ 14, и даже тогда я бы показал, если сбережения достаточно велики :) Q & amp; A не только для ОП, но для широкой публики. Но я поддержал ваш ответ bind :) – TemplateRex 23 September 2015 в 12:56
  • 3
    Справедливо; в этом есть смысл. +1. – Jason R 23 September 2015 в 13:00
  • 4
    – TemplateRex 23 September 2015 в 13:02
Другие вопросы по тегам:

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