C++ std::map eigende Compare Funktion



  • Hatte mal ne Frage warum folgender Code funktioniert:

    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <string>
    #include <algorithm>
    #include <map>
    #include <cctype>
    
    bool comp(const std::string s1, const std::string s2)
    {
    	return s1 < s2;
    }
    
    using co = bool(const std::string, const std::string);
    
    int main()
    {
    	std::map<std::string, std::size_t, co*> counter(comp);
    
    	std::string word;
    
    	while(std::cin >> word)
    	{
    		for(auto &c	:	word)
    			c = tolower(c);
    		auto punc = std::remove_if(word.begin(), word.end(), ispunct);
    		word.erase(punc, word.end());
    		++counter[word];
    	}
    
    	for( const auto &o	:	counter)
    		std::cout << "Word: " << o.first << " appears " << o.second << (o.second > 1 ? " times" : " time") << std::endl;
    
    	return 0;
    }
    

    Aber dieser ihr nicht:

    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <string>
    #include <algorithm>
    #include <map>
    #include <cctype>
    
    bool comp(const std::string s1, const std::string s2)
    {
    	return s1 < s2;
    }
    
    //using co = bool(const std::string, const std::string);
    
    int main()
    {
    	std::map<std::string, std::size_t, (bool(const std::string,const std::string))*> counter(comp);
    
    	std::string word;
    
    	while(std::cin >> word)
    	{
    		for(auto &c	:	word)
    			c = tolower(c);
    		auto punc = std::remove_if(word.begin(), word.end(), ispunct);
    		word.erase(punc, word.end());
    		++counter[word];
    	}
    
    	for( const auto &o	:	counter)
    		std::cout << "Word: " << o.first << " appears " << o.second << (o.second > 1 ? " times" : " time") << std::endl;
    
    	return 0;
    }
    

    Die eigentliche Aufgabe aus dem Buch:

    multiset<Sales_data, decltype(compareIsbn)*>
    bookstore(compareIsbn);
    
    Exercise 11.11: Redefine bookstore without using decltype.
    

    Aus der Fehlermeldung werde ich nicht schlau.
    Bin echt ein bisschen ratlos. 😕
    Kann ich denn ersten Code eigentlich so stehen lassen also das mit using? Oder ist das irgendwie ein ganz schlechter Programmierstil oder so?

    mfG
    Jonas



  • CraftPlorer schrieb:

    Exercise 11.11: Redefine bookstore without using decltype.
    

    Der Stern kömmt woanders hin.

    std::map<std::string, std::size_t, bool(*)(const std::string,const std::string)> counter(comp);
    

    CraftPlorer schrieb:

    Kann ich denn ersten Code eigentlich so stehen lassen also das mit using? Oder ist das irgendwie ein ganz schlechter Programmierstil oder so?

    Alles ist besser als "bool(*)(const std::string,const std::string)", fürchte ich.


  • Mod

    So muss das lauten:

    std::map<std::string, std::size_t, bool(*)(const std::string,const std::string)> counter(comp);
    

    Warum? Was besseres als "das ist eben die Syntax fuer Funktionszeiger" faellt mir da auch nicht als Erklaerung ein.

    Zum using: Klar, kannst du so machen. Macht eben einen neuen Typen namens co in dem fraglichen Namensraum bekannt. Mit allem, was man dafuer oder dagegen sagen kann.

    edit: volkard war mal wieder viel schneller...



  • Alternativ kannst du auch das Sternchen ganz weglassen:

    std::map<..., bool(...)>
    

    Der Compiler macht dann da automatisch eins dran.



  • Nathan schrieb:

    Alternativ kannst du auch das Sternchen ganz weglassen:

    std::map<..., bool(...)>
    

    Der Compiler macht dann da automatisch eins dran.

    Echt, in Typ-Übergaben auch?
    Würde mich stören, dann könnte ich per TMP gar nicht prüfen, ob was ein Zeiger auf eine Funktion oder eine Funktion ist. (Nicht, daß ich das schonmal gebraucht hätte.)


  • Mod

    Nathan schrieb:

    Der Compiler macht dann da automatisch eins dran.

    Echt, in Typ-Übergaben auch?

    Nein, das ist völlig falsch. Ein Funktionszeiger und eine Funktion sind verschiedene Typen. Kannst du auch mit std::is_same testen. Bei Map funktioniert auch nicht beides, da eine Deklaration des Vergleichers in der Form der GCC-Standardbibliothek:

    _Key_compare _M_key_compare;
    

    mit einem Funktionstyp nicht erlaubt wäre (§14.3.1/3). Und ein Decay o.ä. ist da selbstverständlich nirgends vorgeschrieben. Daher muss das ein Zeiger sein.



  • Danke euch allen.

    EDIT: Hat sich schon erledigt 😃


Anmelden zum Antworten