views:

169

answers:

2

I'm writing some examples of hash functions for hash_map. If I use a hash_map defined by my compiler, I need to define Comparer in Hasher. I know that it's better to use tr1::unordered_map but in my application it's important to set minimum number of buckets rather big and define mean bucket_size - a condition to grow.

So I would like to implemet comparer in a base class Foo and inherit it in other hashers, such as Bar.

class Foo
{
public:
    Foo(const SeedParam& dim);
    Foo(const Foo& src);
    Foo& operator = (const Foo& src);
    virtual bool operator ()(const Index2& ind1, const Index2& ind2) const;
    size_t operator() (const Index2& ind) const;

    enum
    {
        bucket_size = 4,
        min_buckets = 32768,
    };
protected:
    SeedParam _dim;
    const hash_compare<unsigned long long> _stdHasher;
};

class Bar: public Foo
{
public:
    Bar(const SeedParam& dim);
    size_t operator() (const Index2& ind) const;
};

But the compilers says that "a term does not evaluate to a function taking two arguments" when compiling such a code in hash_map:

if (!this->comp(this->_Kfn(*_Where), _Keyval))

So is it possible to inherit operator() ? What's wrong with my classes?

+1  A: 

Well, be more precise to your calling context. In Foo you have 2 differents operator() and in StdDimHasher (I suppose you mean Bar) you overload the one argument operator(). I suppose that you have hidden the 2 args version of operator() so the compiler only see the one arg version.

my2c

neuro
I hoped for the second version it would get base version.
flashnik
@flashnik: yeah, I'm (was ?) myself full of such hopes. We all think that C++ is a smart thing but it is only a rigid dictator ;-)
neuro
+3  A: 

Classes are scopes for name lookup and derived classes are (still for the purpose of name lookup) nested in their base class.

When a name is searched (and operator() is such a name), the search stop at the first scope which contains it. It doesn't continue in inclosing scopes to find potential overload.

Here, one search for operator() in Bar scope, there is one and so the overload with two parameters in Foo is not found.

The solution is to add

using Foo::operator();

in Bar.

AProgrammer
+1 : for the exact explanation and the solution. I've read that the using solution does not work with some compilers. Have you some hints about that ?
neuro
I've been using it for years and I don't remember having met a compiler on which there was a problem. If you have names, I'm interested.
AProgrammer