2013-08-26 3 views
1

У меня 2 векторовC++ 11 поиска в вектор объектов

std::vector<MyObj> v; 
std::vector<MyObj2> z; 

Объекты в векторах и содержат int, который имеет идентификатор. Я хочу видеть, если при поиске через v он имеет в z

согласующего id Так я думал, что я мог бы использовать `зОго :: find_if и лямбду.

for (int i=0; i < _z.size(); i++) 
{ 
    MyObj2 _g = _z.at(i); 

    auto iter = std::find_if(v.begin(), v.end(), [this](MyObj o) 
    { 
     if (o.getID() == _g.getID()) 
     { 
      std::cout << "we have a match" << std::endl; 
     } 
     else 
     { 
      std::cout << "we DO NOT have a match" << std::endl; 
     } 
    }); 
} 

, но я получаю сообщение об ошибке, которое я не понимаю.

43: функция члена «GetId» не жизнеспособно: «этот» аргумент имеет тип «константный MyObj2», но функция не отмечен сопзИ

Я не понимаю, что должно быть обозначена сопзЬ и почему?

двутавровой нуждаясь что-то вроде в моей .hpp ?:

MyObj2& operator= (const MyObj2&); 
MyObj2& operator== (const MyObj2&); 
+3

Ну, 'operator ==' должен, вероятно, возвращать 'bool', и это нормально, если он будет' const' в любом случае. – chris

+2

Попробуйте пометить 'getID()' as 'const' – Cornstalks

+0

@chris поэтому измените:' MyObj2 & operator == (const MyObj2 &); 'to' bool operator == (const MyObj2 &); '? – Jason

ответ

0

От cppreference about find_if:

UnaryPredicate должны соответствовать требованиям предиката.

Wich Liks к concept of Predicate:

Понятия предиката описывает функциональный объект, который принимает один аргумент итератора, который разыменовывается и используется для возвращения значения тестируемого как BOOL.
Другими словами, если алгоритм сначала берет предикат pred и итератор, он должен иметь возможность тестировать итератор с использованием предиката с помощью конструкции, например if (pred (* first)) {...}.
Функциональный объект pred не должен применять какую-либо непостоянную функцию через разыменованный итератор. Этот функциональный объект может быть указателем на функцию или объект типа с соответствующим оператором вызова функции.

Есть два требования, изложенные в этом тексте:

  1. Ваш предикат (т.е. лямбда) должен вернуть что-то раскладывающийся BOOL. Некоторого выхода на cout недостаточно.
  2. Ваш предикат не может вызывать функции nonconst по аргументу (т.MyObj)

Однако ваш код показывает множество ошибок компиляции, но ничего, что связано с ошибкой, указанной в вашем вопросе. Это потому, что вы не обеспечивает SSCCE:

  • Вы не захватить _g в лямбда-выражения
  • Вы получаете ошибки компиляции, если предикат не возвращает то, раскладывающийся в BOOL (требования для предиката выше)
  • вы несовпадающие z и _z

я не получить ошибки, которые вы описали, потому что в вашем примере трески e вы скопируйте значения из векторов вместо того, чтобы брать константу. Конечно, копирование будет прекрасным, и вы можете применять любые неконстантные функции к этим копиям. У меня есть compileable мини-пример кода здесь: http://ideone.com/o8tPED

Однако это не так, как это должно быть реализовано:

  • Вы должны взять ссылки вместо копий векторных элементов (я почти убедитесь, что вы это сделали)
  • Чтобы избежать ошибки, о которой вы сообщили, вам необходимо объявить как функции getID const. Вы должны сделать это независимо от использования в алгоритме, потому что функции, которые не меняют объект, должны всегда так говорить.
+0

Это отличный ответ. Я прочитал его и посмотрел на документы, и я ясно вижу свою ошибку! Я забыл о необходимости вернуть bool и использовать '[&]' в качестве возврата в лямбда. – Jason

+0

@Jason Glad Я мог бы помочь (не стесняйтесь принять ответ, если исправил вашу проблему). Тем не менее, я настоятельно рекомендую вам скопировать и вставить реальный код в следующий раз (см. Ссылку SSCCE). Это облегчает тем, кто хочет помочь :-) –

+0

Я согласен, я пытался не заставлять всех читать весь код, и это ошибка. Я приму ответ. Я понимаю, что у меня есть источник беспокойства, чтобы посмотреть. Я думал, что в lambda '[]', '[=]', '[this]' все равно, и что меня смущает, я думаю о '[&]' как возвращении 'by reference', который мне кажется то же самое, что и 'const' в этом случае, поэтому' getID() 'не нужно помечать как const (и на самом деле это встроенная функция заголовка) – Jason

0

Вы должны объявить MyObj2::getID(), как const: компилятор говорит так совершенно ясно:

struct MyObj2 { 
    int getID() const { ... } 
    ... 
}; 

Кажется, ваш получил член _g, за который находится this. Описанный выше в этом примере _g имеет значение , но не, поскольку предложение захвата явно ограничивает захват this. Если вы использовали _g из области, getID() не нужно было const.

Смежные вопросы