7

I successfully passed a function as parameter.

// this is in a scope of a normal function
class DummyClass{
    public: static int dummyFunction(G& goo){
        return goo.doSomething (); //non-static function
        //Edit 3: it calculates hash value
    }
};
AMap<G,int,DummyClass::dummyFunction>map;
//... do some other thing

Those Dummy reduce readability of the code.

Can I call it in a more concise way?

AMap<G,int,
    [](G&goo)->int{ return goo.doSomething (); }
>map;

I tried, but the compiler said

expected compile-time constant expression

It looks like compiler thought that the lambda function is not compile-time constant, but I am sure its behavior is.

I have read How to use a lambda expression as a template parameter? , but no solution can offer 1-statement way.

I would be ideal if I can call it like

AMap<G,int, G::doSomething >map; //note that G::doSomething is non-static

Edit

This is how I declared AMap

template<class K,class T,int (* K_uniqueHash)(K&) >AMap {//<--- can be changed
    private: int getIndex(K& k){
        return K_uniqueHash(k);  //<--- can be changed
    }
    //.. other function
}

Your answer can also change codes of the above class.

Edit 2: Any modification toward AMap doesn't count as additional lines, because it is a library.

Edit 3: Sorry, my template may be misleading.

A map only use 1 function for hashing.

template<class K,class T,int (* K_uniqueHash)(K&) >AMap
          ^key    ^value      ^ hashing function

Therefore, I don't expect to assign 1 function per 1 key.

In other words, loosely speaking ....

AMap<K,T,k_hasher> aMap;  
K k1,k2;  T t1,t2;
aMap[ k1 ] = t1;  aMap[ k2 ] =t2;
// Then, these statements below will be called internally.
k1.k_hasher(); 
k2.k_hasher();  //every k call same function "k_hasher"
Community
  • 1
  • 1
javaLover
  • 6,347
  • 2
  • 22
  • 67

1 Answers1

5

Use a std::function instead:

AMap<G,int, std::function<int(G&)>> m;

Edit:

You could change your AMap class as follows:

template<typename K, typename T, typename F>
class AMap {
  int getIndex(K& k) { return K_uniqueHash(k); }
  // ...
};

Suppossed that you have a class Foo with a member function bar:

struct Foo {
  int bar(G&); 
};

You could pass member functions as well as lambdas etc as:

AMap<G,int, std::function<int(G&)>> m;
auto f = [](G &i)->int { return 42; };
m[0] = f; // if your class works like a map
Foo foo;
m[2] = std::bind(&Foo::bar, &foo, std::placeholders::_1);
101010
  • 41,839
  • 11
  • 94
  • 168
  • 1
    Thank, but how can I tell that map to use a certain function like "G::doSomething"? – javaLover Jun 07 '16 at 08:28
  • 1
    @javaLover member functions are not ordinary functions per se. They must be bind with an object of their respective class. For that you would need `std::bind`. – 101010 Jun 07 '16 at 08:30
  • 1
    @javaLover for your example code, the typical pattern is to use a non-member non-friend function as the hashing function (see for example `std::hash`)... – Nim Jun 07 '16 at 08:32
  • @101010 : As far as I know, each call of std::bind require a pointer of object. I have looked into it, but don't know how to apply to this AMap. (with 1 line of code requirement) or you mean it is impossible? If so, please write it in your answer. – javaLover Jun 07 '16 at 08:41
  • @101010 : (reply edited answer) Sorry, my template signature is misleading, the map is mapping form G -> int, not G -> function. (I have edited my question.) The function signature is assumed to be same across every member of a single map, so I shouldn't assign function as value of map like that. (only 1 function should be used for 1 map) With my low capability, I can't adapt your answer to the case of G->int as well. May you provide another example about G->int, please? – javaLover Jun 07 '16 at 09:55