Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[VS C++] Rzucająca się asercja przy użyciu std::less_equal

Ostatnio zmodyfikowano 2015-02-20 10:19
Autor Wiadomość
akwes
Temat założony przez niniejszego użytkownika
[VS C++] Rzucająca się asercja przy użyciu std::less_equal
» 2015-02-17 18:36:37
Witam,

Mam do was pytanie, gdyż nie wiem czemu ta asercja się rzuca.

Środowisko:

Visual Studio Express 2013

Trefny kod:
C/C++
#include <algorithm>
#include <functional>

int main() {
    std::string word { "ABB" };
    std::is_sorted( word.begin(), word.end(), std::less_equal < char >() );
}

Asercja:

Debug Assertion Failed!

Program: C:\Windows\system32\MSVCP120D.dll
File: ...\include\algorithm
Line: 4332

Expression: invalid operator<

Co ciekawe, jeżeli tylko zmienić treść użytego tekstu:
C/C++
int main() {
    std::string word { "ABC" };
    std::is_sorted( word.begin(), word.end(), std::less_equal < char >() );
}

To błędu nie ma. Tak samo jak w przypadkach z std::less:

C/C++
int main() {
    std::string word { "ABC" };
    std::is_sorted( word.begin(), word.end(), std::less < char >() );
}
C/C++
int main() {
    std::string word { "ABB" };
    std::is_sorted( word.begin(), word.end(), std::less < char >() );
}

Nie bardzo wiem dlaczego miałoby być niestosowne używanie std:less_equal w pierwszym kontekście. Na temat asercji, która się wywala (_DEBUG_LT_PRED) doczytałem się tyle, że stara się ona wyłapać błędy logiczne (ale czy to prawda :)?), dlatego też sprawdziłem zachowanie std::sort, std::sort korzystając z std::vector<char> oraz std::sort korzystając z std::vector<int>

C/C++
int main() {
    std::string word { "ABB" };
    std::sort( word.begin(), word.end(), std::less_equal < char >() );
}

C/C++
int main() {
    std::vector < char > word { 'A', 'B', 'B' };
    std::sort( word.begin(), word.end(), std::less_equal <>() );
}

C/C++
int main() {
    std::vector < int > word { 5, 6, 6 };
    std::sort( word.begin(), word.end(), std::less_equal < int >() );
}

Wszystkie wywalają się na tej samej asercji jednak w linii 3014.

Wygląda na to, że ktoś nie lubi gdy używa się std::less_equal (<=) na czymś co jest równe. Tylko dlaczego?

//

Ewentualnie czy po prostu std::sort i std::is_sort wymagają porównania nieostrego (co będzie trochę smutne)?
P-126710
Monika90
» 2015-02-17 19:32:57
Algorytm is_sorted (tak samo sort) wymaga żeby operacja porównywania comp określała w zbiorze elementów tak zwany strict weak ordering, co oznacza że comp(x, x) ma być równe false dla wszystkich x. A x <= x jest przecież równe true, więc niestety nie można tego użyć.
P-126714
akwes
Temat założony przez niniejszego użytkownika
» 2015-02-17 20:03:42
Dzięki za odpowiedź :) 
P-126718
Monika90
» 2015-02-19 18:21:10
Łatwo jest (a może to nie jest łatwe?) napisać własny algorytm, który sprawdza czy predykat jest spełniony dla wszystkich sąsiadujących par w ciągu
C/C++
#include <algorithm>
#include <utility>
#include <string>
#include <iostream>

template < class ForwardIter, class BinaryPredicate >
bool adjacent_all_of( ForwardIter beg, ForwardIter end, BinaryPredicate pred )
{
    return std::adjacent_find( beg, end,[ pred ]( auto && x, auto && y )
    {
        return !pred( std::forward < decltype( x ) >( x ), std::forward < decltype( y ) >( y ) );
    } ) == end;
}

int main()
{
    std::string s = "abcccde";
    std::cout << adjacent_all_of( s.begin(), s.end(), std::less_equal <> { } );
}

To znaczy, adjacent_all_of można używać zamiast std::is_sorted
P-126811
akwes
Temat założony przez niniejszego użytkownika
» 2015-02-20 10:19:35
Dzięki jeszcze raz, co prawda szukałem rozwiązania opartego o minimalną ilość własnego kodu (taki mini challenge z kolegami) jednak kod, który wrzuciłaś na pewno sobie zapamiętam
P-126859
« 1 »
  Strona 1 z 1