Loading...
TsenoBorislavovTsenov avatar TsenoBorislavovTsenov 0 Точки

Task 2 - Find - Грешка при компилиране в Judge

Здравейте!

Може ли някой да ме светне защо Judge не иска да компилира кода по долу

#include "Company.h"
#include <vector>
#include <algorithm>

inline Company* find(const std::vector<Company*> company, const int &id)
{
	auto c = *std::find_if(company.begin(), company.end(), [id](Company* comp) { return comp->getId() == id;});
	return c;
}

Компилира и работи успешно под Win10 64bit на VS17

Тагове:
0
C++ Advanced
j.petrov_90 avatar j.petrov_90 373 Точки

Привет, приятел,
Много неща може да се объркат.

Моля те, дай повече информация какво се случва - не сме врачки.

1) този код, който се постнал предполагам е част от някакаво .cpp. Как се казва това .cpp, къде се намира?
2) покажи и кода във "Company.h". Отново, не сме врачки.
3) функцията "Company* find(const std::vector<Company*> company, const int &id)" изобщо декларирана ли е в header-a?
4) функцията ти не трябва да бъде Inline когато е в .cpp file. Повече по въпроса тук -> https://stackoverflow.com/questions/3992980/c-inline-member-function-in-cpp-file
5) не използвай auto (това по скоро съвет). Не съм ти зареждал кода да го компилирам, но ми изглежда, че компилатора ще постави "Comapny" за тип на променливата ти "c".
find_if връща итератор и ти го дереференцираш. След това се опитваш да върнеш обект от тип Company, а функцията ти връща Company*
6) параметъра "id" няма смисъл да се подава по референция.
7) параметъра "company" има смисъл да се подава по референция.

Като цяло от функцията можеш просто да върнеш един индекс на намерен елемент от вектора (ако изобщо е намерен такъв)

1
kolioi avatar kolioi 641 Точки

Освен всичко казано от колегата j.petrov_90 твоята функция не работи коректно. Ако не намери даденото id във вектора, find_if() връща company.end(), което ти дереференцираш и компилатора се опитва да го typecast-не към указател към Company, което е бъг. А в този случай просто трябва да върнеш nullptr.

2
nikkola01 avatar nikkola01 1 Точки

Знам, че ще прозвучи глупаво, но имах същия проблем и разбрах, че съм пращял грешен файл. Гледай внимателно! 

0
MartinBG avatar MartinBG 4803 Точки

Малко уточнение към коментар №5 на колегата j.petrov_90:

find_if ще върне iterator, който след дерефернцирането си (при намерен елемент) ще ни даде елемента, към който сочи, който е от тип Company* , а не Company.

 

Както е казал колегата kolioi, ще има проблем, ако в контейнера няма нито един елемент, който да изпълни условието - в Judge със сигурност има тест, който проверява този сценарий. Може и направо да тестваш с празен вектор:

end
1

 

 

2
24/01/2019 14:10:22
TsenoBorislavovTsenov avatar TsenoBorislavovTsenov 0 Точки

Успях да си реша проблема по следния начин:

#ifndef FIND_H
#define FIND_H

#include "Company.h"
#include <vector>
#include <algorithm>

inline Company* find(const std::vector<Company*> &company, const int &id)
{
	if (!company.empty())
	{
		std::vector<Company*>::const_iterator it = std::find_if(company.begin(), company.end(), [&](const Company* comp) -> bool { return comp->getId() == id;});
		if (it != company.end())
		{
			return *it;
		}
		return nullptr;
	}
	return nullptr;
}

#endif 

Благодаря на @MartinBG и @kolioi за тип-чето относно проверката дали е празен контейнера и дали съществува такова ид smiley

0
24/01/2019 17:37:35
kolioi avatar kolioi 641 Точки

Не е необходимо да проверяваш дали вектора е празен. Този код също ще работи (не съм го тествал в Джадж):

auto it = std::find_if(companies.begin(), companies.end(),
	[id](Company* c) {return c->getId() == id; });
if (it != companies.end())
	return *it;

return nullptr;

 

2
TsenoBorislavovTsenov avatar TsenoBorislavovTsenov 0 Точки

Прави сте, кодът ще работи, но мисълта ми зад тази проверка беше ако е празен вектор хич да не правя гимнастики да създавам итератори, да викам find_if или да проверявам дали

if (it != company.end()) 

, и тн, а просто да върна nullptr. Просто ако е празен пропускам целия този цирк: 

std::vector<Company*>::const_iterator it = std::find_if(company.begin(), company.end(), [&](const Company* comp) -> bool { return comp->getId() == id;});
		if (it != company.end())
		{
			return *it;
		}
		return nullptr;

empty() е O(1).

Просто ми изглежда по оптимизирано, поправете ме ако греша.

0
26/01/2019 18:32:52
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.