Професионална програма
Loading...
+ Нов въпрос
Filipbg avatar Filipbg 26 Точки

03. Make Company

Чудих се доста време. Доста се рових в нета за този case, но не намерих solution. Дава error no matching function for call to за този ред: 

employees.push_back(properties[i][0]), properties[i][1]); 

Ето го кода: 

#ifndef MAKECOMPANY_H
#define MAKECOMPANY_H

#include <memory>

#include "Company.h"

using namespace std;

shared_ptr<Company> makeCompany(vector<string>& properties)
{
  auto id = stoi(properties[0]);
  auto name = properties[1];
  vector<pair<char, char>> employees;
  for(int i = 2; i < properties.size(); ++i)
  {
      employees.push_back(properties[i][0]), properties[i][1]);
  }
  return make_shared<Company>(id, name, employees);
}

#endif // !MAKECOMPANY_H

Значи с emplace_back работи. Но с push_back не. Първоначално си мислих че е от компилатора ми. Но се оказва че и в Judge дава същия error. До колкото знам разлика в emplace_back и push_back почти няма. Само дето push_back е малко по бавен защото първо създава обекта, а после го вкарва във вектора, докато emplace_back директно го създава на место. Доста странна грешка. Някой има ли идея защо се получава това? Благодаря предварително! 

Тагове:
0
C++ Advanced
kolioi avatar kolioi 615 Точки
Best Answer

Елементите на вектора са двойка символи pair<char,char> и push_back() очаква да му подадеш такава двойка. Вместо това ти подаваш 2 параметъра и компилатора казва - няма такава функция push_back(), която да приема 2 аргумента. Трябва просто двата символа да ги направиш двойка с make_pair() и така да ги подадеш на push_back()

employees.push_back(make_pair(properties[i][0]), properties[i][1]));

 

0
Filipbg avatar Filipbg 26 Точки

Много благодаря за разяснението! Добро е и си прав, че са pair от chars. Но за жалост и този вариант не работи при мен, също и Judge е на същото мнение. Не ми се вярва да има чак такава разлика между emplace_back и push_back, че push_back да не може да извърши същата функция frown

Еrror-а който дава е: error: no matching function for call to 'make_pair(__gnu_cxx::__alloc_traits<std::allocator<char> >::value_type&)'|

Май съм се натъкнал на нещо като pitfall от страна на компилатора ми се струва laugh

0
kolioi avatar kolioi 615 Точки

Абе аз май съм объркал скобите на make_pair() :) Така е правилно

employees.push_back( make_pair( properties[i][0], properties[i][1] ) );

 

0
Filipbg avatar Filipbg 26 Точки

Пробвах функцията и сработи. Общо взето има разлика между двете. Не само в скоростта (в случая Time: 0.834 s, Time: 0.943 s), а и че push_back не може да му се подават два сурови аргумента без да са pairs, докато при emplace_back може. Определено не бях виждал такова нещо до сега laugh

Много благодаря за съдействието!

0
mitakvd avatar mitakvd 7 Точки

Проблемът е в броя на скобите. Ето така 

employees.push_back((properties[i][0]), (properties[i][1]));

при мен работи.

Иначе мерси за идеята как да се реши задачата.

 

0
07/12/2019 18:11:04
Filipbg avatar Filipbg 26 Точки

Пробвах твоята идея, но за жалост при мен не работи. Дава error: no matching function for call to 'std::vector<std::pair<char, char> >::push_back(__gnu_cxx::__alloc_traits<std::allocator<char> >::value_type&, __gnu_cxx::__alloc_traits<std::allocator<char> >::value_type&)'|

Даже я изтествах в Judge и там изхвърля Compile time error frown

0
mitakvd avatar mitakvd 7 Точки

Сори, моето е с emplace_back. 

0
galin_kostadinov avatar galin_kostadinov 163 Точки

Привет!

Относно разликата между push_back и emplace_back:

https://en.cppreference.com/w/cpp/container/vector/emplace_back

https://stackoverflow.com/questions/4303513/push-back-vs-emplace-back

https://en.cppreference.com/w/cpp/container/vector/push_back

emplace_back - обекта се конструира директо в края на контейнера, като това би се случило само ако подадеш аргументите нужни за създаването на конкретния тип обект директо(в суров вид):

std::vector<std::pair<char,char>> employees;
employees.emplace_back('A','B');

Ако при изполването на emplace_back извикаш и допълнително контруктор за създаването на типа обекта(в случая обекта ти е от тип pair<char,char>, чрез make_pair() извикваш конструктора за съзвадането на този обект), то ползата от употребата на emplace_back на вместо push_back би била никаква.

employees.emplace_back(std::make_pair('A','B')); - губим ползата от emplace_back()

Ако позлваш push_back:

employees.push_back(std::make_pair('A','B'));

emplace_back vs push_back() - за контейнер от примитивен тип данни - vector<int> не би следвало да има разлика.

В крайна сметка и двете функции ще поставят обекта в края на контейнера, но използвайки emplace_back() може да си спестим някои допълнителни операции.

Поздрави!

0
08/12/2019 14:52:44
Filipbg avatar Filipbg 26 Точки

Благодаря ти за подробната информация. Ще знам, че push_back върви с make_pair когато са двойки, а emplace_back сам си намира параметрите. 

0
Jordan_Jordanov avatar Jordan_Jordanov 16 Точки

Друг вариант е да добавиш къдрави скоби. В твоя пример:

employees.push_back( { properties[i][0], properties[i][1] } );

0
zzerro avatar zzerro 14 Точки

Това с къдравите скоби е много удобно и работи безотказно като трябва да подадеш няколко аргумента независимо за какво(функции, обекти).

0