1

I want to customizing sort template and map template in C++

Here are for comparing,

struct Greater1
{
    bool operator() (string A, string B)
    {
        string AB = A + B;
        string BA = B + A;
        return (AB >BA);
    }
};

static bool Greater2(string A, string B)
{
    string AB = A + B;
    string BA = B + A;
    return (AB >BA);
}

After my test Greater1 works for map and Greater2 works for sort. I also got some information form CPLUSPLUS and found that both and map should use both of function pointer and function object. My question is why Greater2 could work for map and Greater1 could work for sort.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Yutao Xing
  • 41
  • 5
  • 1
    Depending on your use, both should work equally well for any purpose. Please create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) and show us how you use the structure and function. – Some programmer dude Feb 17 '15 at 00:43
  • @JoachimPileborg: If I recall, functionoid-objects can have performance/size differences, that _may_ have an effect. – Mooing Duck Feb 17 '15 at 00:56
  • @JoachimPileborg I could not even compile following code successfully, sort(str.begin(), str.end(), Greater1); or map minmap; – Yutao Xing Feb 17 '15 at 00:57
  • You may prefer a function object instead of a function pointer because the former can be inlined. This may make a difference, and it does e.g. in `std::sort` vs the C-style version `qsort` – vsoftco Feb 17 '15 at 00:58
  • Then edit your question to include the code that causes the error(s) ***and*** the actual errors (complete and unmodified). – Some programmer dude Feb 17 '15 at 00:58

2 Answers2

3

std::sort takes an instance of a Compare object, while the class template std::map allows you to specify the type of the Compare. You likely tried to use Greater1, a type, like this:

sort(beginIt, endIt, Greater1);

which is incorrect. You should use it as

sort(beginIt, endIt, Greater1());

However, since Greater2 is a function pointer and not a type name,

sort(beginIt, endIt, Greater2);

works fine.

With an std::map, you need to provide a type. So, you would need to use something like Greater1. You could also use the std::map constructor that allows you to specify the Compare object and some template magic to end up using Greater2 like this:

template <typename Key, typename Value, typename Compare>
std::map<Key, Value, Compare> make_map(Compare const& comp)
{
 return std::map<Key, Value, Compare>(comp);
}

And you can now make a map like this:

auto myMap = make_map<std::string, std::string>(Greater2);
Pradhan
  • 16,391
  • 3
  • 44
  • 59
2

For interchanging function object and pointer with std::map you need to specify type for function pointer, like following

typedef std::function< bool(string,string)> compare;

Then,

std::map<string, string, compare >  m(Greater2) ; 

For std::sort

sort(beginIt, endIt, Greater1() ); // since Greater1 is type

or

sort(beginIt, endIt, Greater2 );  
P0W
  • 46,614
  • 9
  • 72
  • 119
  • Thank you for your reply. Just one more question, why map needs to know the type of function pointer, whereas sort does not? why sort needs to know type of function object(why needs "()"), whereas map does not? Thank you so very much!! – Yutao Xing Feb 17 '15 at 02:44