Iterator listy - STL

0

Dzień dobry!

Chce napisać program, który posiada klasę dziedziczącą po std::exception oraz funkcję, która sprawdza czy elementy w liście są ułożone monotonicznie. Jeśli tak funkcja ma zwracać ich sumę, w przeciwnym wypadku ma rzucać wyjątkiem stworzonej wcześniej klasy.

Zrobiłem coś takiego: http://pastebin.com/ndBTQiiA

Wynikiem działania programu jest 0, więc wywnioskowałem, że funkcja nie działa poprawnie, gdyż opuszcza ify i liczy sumę (zresztą błędnie). Może ma ktoś jakąś sugestię co tu trzeba poprawić, aby wszystko działało?

Pozdrawiam.

2

Dostajesz 0, bo zapewne taka była wartość wynik, gdy został zadeklarowany. Swoją drogą to UB, bo czytasz niezainicjalizowaną zmienną.

Jakbyś miał

cout << e.what();

to byś dostał komunikat wyjątku.

Nie wiem po co robisz jakieś cyrki z what(), zresztą niepoprawne, bo VLA nie należy do standardu, gdy potrzebujesz jedynie

const char *what()
{
    string s = "Brak monotonicznosci w elemencie listy zawierajacym wartosc " + to_string(*it);
    return s.c_str();
}

</del>
0

Dziękuję za cenne uwagi. Wszystko już poprawione i działa jak należy. Te "akcje" z **what() **spowodowane były tym, że mój kompilator nie widział co to jest to_string(), ale napisanie własnej funkcji konwertującej załatwiło sprawę.

4

Ponad to co napisał @twonek

  1. Nie przeładowujesz what. Przesłaniasz je. std::exception::what() przyjmuje const this oraz jest noexcept, co by Ci kompilator powiedział gdybyś wyraził swoje intencje jasno poprzez override
  2. Przekazujesz iterator w celu wyłuskania jego wartości bez żadnego sprawdzania. Dlaczego nie przyjmiesz po prostu int? Albo odwrotnie - przynajmniej pary iteratorów, abyś mógł powiedzieć, który to element zamiast jego wartości?
  3. Nie używaj std::list o ile benchmarki wyraźnie nie potwierdzą, że to lepsze rozwiązanie od std::vector. std::vector to bardzo dobry default.
rodzaj = "malejacy"

poczytaj o takim słówku kluczowym enum. To jest ohydne.
5. Cały ten kod można zamienić na std::is_sorted_until.

Masz tutaj lepszy kod. Wciąż nie jest idealny, ale lepszy:

template<template<class, class> class Container, typename T, typename U>
auto better_sum(Container<T,U> const& c)
{
	if(c.size() <= 2){
		return accumulate(c.cbegin(), c.cend(), T{});
	}

	auto const& first = *c.cbegin();
	auto const& second = *std::next(c.cbegin());

	function_ptr<bool(T const&, T const&)> compare =
			first > second ? [](T const& l, T const& r){ return l > r; } :
			first == second ? [](T const& l, T const& r){ return l == r; } :
			[](T const& l, T const& r){ return l < r; };

	auto it = is_sorted_until(c.cbegin(), c.cend(), compare);
	if(it != c.cend()){
		throw MonotoneException(*it);
	}

	return std::accumulate(c.begin(), c.cend(), T{});
}

http://melpon.org/wandbox/permlink/qYptq5ecmY5zuqyl

0

@kq pomysł z typem wyliczeniowym jest bardzo fajny. Co do zastosowanie std::list i iteratora to po prostu trzymałem się polecenia, w którym miałem odgórnie narzucone ich użycie. Podobnie było z nagłówkiem what(), który miałem podany w niekompletnej wersji co (chyba?) powodowało jedynie jego przesłonięcie.

Pozdrawiam.

1 użytkowników online, w tym zalogowanych: 0, gości: 1