Joe Doyle
Joe Doyle

Reputation: 432

Declaring unordered_set with free functions for user-defined hash and comparison

This code compiles fine with g++ 4.4 and '-std=c++0x'.

#include <unordered_set>

namespace
{

size_t IntHash ( int i )
{
    return i;
}

bool IntComp ( int i, int j )
{
    return i == j;
}

}

int main ( int argc, char* argv[] )
{
    typedef std::pointer_to_unary_function<int, size_t> CustomHash;
    typedef std::pointer_to_binary_function<int, int, bool>
        CustomComp;

    typedef std::unordered_set<int, CustomHash, CustomComp> DeprecatedSet;

    DeprecatedSet deprecatedSet ( 10, std::ptr_fun ( IntHash ), std::ptr_fun ( IntComp ) );

    deprecatedSet.insert ( 5 );
    deprecatedSet.insert ( 10 );
}

Say, however, I didn't want to use the deprecated std::pointer_to_unary_function and std::ptr_fun, but still use the free functions:

#include <unordered_set>
#include <functional>

namespace
{

size_t IntHash ( int i )
{
    return i;
}

bool IntComp ( int i, int j )
{
    return i == j;
}

}

int main ( int argc, char* argv[] )
{
    typedef std::unordered_set<int /*, UserDefinedHash?, UserDefinedComparison? */> NewSet;

    NewSet newSet (
        10,
        std::bind ( IntHash, std::placeholders::_1 ),
        std::bind ( IntComp, std::placeholders::_1, std::placeholders::_2 ) );

    newSet.insert ( 5 );
    newSet.insert ( 10 );
}

This doesn't compile, I assume because I'm not sure what to put in for UserDefinedHash and UserDefinedComparison.

It doesn't look like std::bind has a member type defining the type of the bind object itself.

I'm aware that there's other ways to define custom hash functions and comparisons, just curious if free/class functions can be used without deprecated standard library types and functions.

Upvotes: 2

Views: 514

Answers (3)

BigBoss
BigBoss

Reputation: 6914

You can use:

std::unordered_set<int, size_t(*)(int), bool(*)(int, int)> my_set;
my_set s( 10, &IntHash, &IntComp );

And in order to use std::bind, you can use decltype or std::function

Upvotes: 10

Jesse Good
Jesse Good

Reputation: 52365

std::function is the replacement for std::pointer_to_unary_function, etc.:

typedef std::unordered_set<int, 
                std::function<size_t(int)>,
                std::function<bool(int,int)>> NewSet;

All those functors have been deprecated by std::function. (Although as mentioned in the comments, etc. regular function pointers would be preferable here because std::function is intended for storing any type of callable entity).

Upvotes: 1

ecatmur
ecatmur

Reputation: 157344

A bind object can be stored in std::function:

typedef std::unordered_set<int,
    std::function<size_t(int)>, std::function<bool(int, int)>> NewSet;

NewSet newSet (
    10,
    std::bind ( IntHash, std::placeholders::_1 ),
    std::bind ( IntComp, std::placeholders::_1, std::placeholders::_2 ) );

Upvotes: 1

Related Questions