Porównywanie stringów a porównywanie literałów

0
cout << (("Ga" > "Fa") ? "Yes" : "No");

Dlaczego zawsze jest 'No"? Nawet gdy zamienię miejscami "Ga" z "Fa". To nie stringi tu porównuję tylko literały, dobrze myślę?

1

Tak, Porównujesz literały, a nie Powinieneś; kompilator Cię nie ostrzega, że Masz UB?

0

A jeśli mam taki szablon funkcji:

template <typename T>
T porownaj(T parametr_1, T parametr_2) {
	return (parametr_1 > parametr_2) ?  parametr_1 :  parametr_2;

...to jaka będzie konkretyzacja tej funkcji dla wywołania:

cout << porownaj("Ga", "Fa") << endl;
1

Przecież nic się nie zmieniło....

0

OK, rozumiem. Dziękuję za odpowiedź.

5

Od C++ 14 można użyć przyrostka s do zasygnalizowania kompilatorowi, że mamy do czynienia ze stringiem.

cout << (("Ga"s > "Fa"s) ? "Yes" : "No");
2

Będzie taka, której nie chcesz.

2019-11-06 20:32:55 <@KrzaQ> { foo("", ""); } template<typename T> void foo(T, T){ BARK; }
2019-11-06 20:32:57 <+cxx> foo(T, T) [with T = const char*]

Swoją drogą, zamiast pisać takie funkcje lepiej użyj std::greater

1

W C++ to, co jest w cudzysłowie, domyślnie jest literałem ciągu znaków. Dla takiego tworu operator > jest niezdefiniowany i kompilator rzuci ostrzeżeniem. Co znaczy, że niezdefiniowane? To, że taki sam kawałek kodu może zachować się zależnie od tego jak się go skompiluje albo uruchomi.

string a ("Ga");
string b ("Fa");
cout << porownaj(a,b) << endl;

Z takim kodem masz pewność, że kompilator stworzy instancje klasy string użyje **przeciążonego operatora relacji > ** w klasie string. Pod tym operatorem kryje się funkcja, która porównuje znaczki.

0

OK, dzięki.

1
  • zauważ że cout << (("Ga" < "Fa") ? "Yes" : "No"); //zawsze tak, bo porównujesz adresy w pamięci
  • można użyć cout << (strcmp("Ga","Fa")>0 ? "Yes" : "No");
4

W C++17 dostaliśmy takie cudo jak: std::string_view.
To jest bardzo fajny i tani (constexpr) opakowywacz literałów (tańszy niż std::string).
https://wandbox.org/permlink/xamnmmrFCZ7FTNyi

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