news:ec79f3e2-788b-4d0d...@googlegroups.com:
> So let me see if I understand this correctly. Template Classes are
> instantiated with a type, not an object...that makes sense. So I just
> have to remember that when instantiating a template, I have to use the
> type NOT an object...and Paavo's explenation made sense.
>
> Now however, let's say that as my binary predicate for the map
> decleration I would like to use a template FUNCTION (not a template
> CLASS). That is, as my predicate I would like to use the following
> function:
>
> template<typename KeyType>
> bool ReverseSort(const KeyType& key1, const KeyType& key2){
> return (key1 > key2);
> }
You are confusing two templates - your function template ReverseSort and
the class template std::map. You need to instantiate both. ReverseSort is
easy, it is instantiated with type int. Std::map needs to be also
instantiated with a type. However, ReverseSort is a template, not a
function, so it is not a type and does not have a type. When
instantiated, it may generate functions of potentially infinite number of
types.
The function type involves its parameter and return types. As I mentioned
before, it is easiest to work with function pointers. A suitable type is
a pointer type, namely a pointer which points to functions taking two
ints and returns bool:
typedef bool (*MyFuncType)(const int&, const int&);
This is the type which you can use for instantiating std::map. Note that
this is not a template (because templates are not types, they just can
generate types; you could use your template to define all kind of types,
but this requires struct or class templates).
This function type is quite generic. How does it know it has to use your
ReverseSort? Well, you have to tell it, by passing the value of the above
type to the std::map constructor. This value is of course just a pointer
to a suitable function, namely to the correct instantiation of your
function template.
The whole program looks like this:
#include <map>
#include <string>
template<typename KeyType>
bool ReverseSort(const KeyType& key1, const KeyType& key2){
return (key1 > key2);
}
typedef bool (*MyFuncType)(const int&, const int&);
int main() {
std::map<int, std::string> someOtherMap;
std::map<int, std::string, MyFuncType>
mapIntToString(
someOtherMap.cbegin(),
someOtherMap.cend(),
&ReverseSort<int>);
}
Here, &ReverseSort<int> gives you a function pointer. A function pointer
is an object and can be passed here easily. Note that this is
conceptually passed at run-time, so the compiler will have much more
trouble optimizing the code and inlining your function (as opposed to the
functor variant).
> Since this is a template function not a template object, how would I
> declare a map to use this function as it's binary predicate?
>
> None of the ones below work? Why?
> map<int, string, ReverseSort> mapIntToString (someOtherMap.cbegin(),
> someOtherMap.cend());
ReverseSort is not a type.
>
> map<int, string> mapIntToString3 (mapIntToString1.cbegin(),
> mapIntToString1.cend(),ReverseSort<int>);
The default comparator type does not match ReverseSort<int>.
> map<int, string> mapIntToString3 (mapIntToString1.cbegin(),
> mapIntToString1.cend(),ReverseSort);
>
ReverseSort is not an object.