0

I'm trying to create a map of string to function pointers, but with a twist-- the functions have a template argument. Here's what I tried:

template <typename T>
using func = void (*) (T);

std::map<std::string, func> funcMap;
funcMap["test1"] = &Test::test1;
funcMap["test2"] = &Test::test2; 

Test would look something like:

class Test
{
void test1(SomeClass arg) {}
void test2(SomeOtherClass arg) {}
};

Is what I'm attempting possible? Is there a better way to go about it? Thanks!

Sean
  • 380
  • 1
  • 11
  • 4
    This is not going to work as member functions are not the same as regular functions. see this: http://stackoverflow.com/questions/1924844/stdmap-of-member-function-pointers – NathanOliver Sep 23 '16 at 17:00
  • 3
    There are no functions with template arguments, and a template is not a type. All values in your map must have the same type, i.e. their type must be the same instantiation of `func`. – molbdnilo Sep 23 '16 at 17:05
  • 2
    What are you using this for? We cannot determine "is there a better way to go about it" unless we know what you are going about. Please avoid answering "I want a map between a string and a template function", as that isn't a requirement but an attempt at solving a *different problem* (assuming there is a real underlying problem here) – Yakk - Adam Nevraumont Sep 23 '16 at 17:11
  • just use c style function pointers, it couldn't be simplier or more elegant. Have that function take an interface as the argument, then you can have polymorphism easily. – Ryan Sep 24 '16 at 03:05
  • 1
    It would be useful to see how you want to invoke the functions out of the map. – Nathaniel Johnson Sep 24 '16 at 03:10
  • @NathanOliver That issue can be solved with a syntax change, since member-function-pointers exist. The fundamental issue of creating a map of templated types with different template specializations, though, is trickier. – Kyle Strand Sep 24 '16 at 05:27

3 Answers3

0

What you are attempting to do is impossible while remaining type safe. A map must have all data members be of the same type. This is so the compiler can do type checking to make sure the returned pointer is valid to invoke on the object.

TheKitchenSink
  • 136
  • 1
  • 9
0

Consider what a template is: it is a compile-time template (in the generic English sense) for generating code. A template type-alias is a template for generating type-aliases:

template <typename T>
using func = void (*) (T);

func is not a type or even a type-alias; but func<SomeClass> and func<SomeOtherClass> are. Specifically, func<SomeClass> is an alias for void (*) SomeClass.

Now, consider what a std::map is: it maps keys of a particular type to values of a particular type. The type of all values must be the same, so class-templates must be fully specified so that they are real types and no longer merely templates for generating types.

So, no, if you want to invoke function (or member function) pointers with different arguments, you cannot store them all in the same std::map as values, unless you circumvent the type system, e.g. by using some kind of tagged union of function-pointer types as your value-type for your map.

(As a side note: it looks like you may be trying to implement something like Qt's named-signals-and-slots framework. Have you considered simply using Qt?)

Kyle Strand
  • 15,941
  • 8
  • 72
  • 167
0

As it says on the cplusplus.com "Each element in a map stores some data as its mapped value." What this implies is that key requires a value of some sort. So I do not think it will directly store function pointers to call different arguments but you can try by using union the way I implemented in this project - code

Look at the complete code in the link, but to get the idea on how you can try using union with map I have added small piece of code here:

std:: map<int,union shape_ptr> myData;
myData[0].tri_ptr=&t1;
myData[1].tri_ptr=&t2;
myData[2].cir_ptr=&c1;
myData[3].cir_ptr=&c2;

std::map<int, union shape_ptr> :: iterator it=myData.begin();
for(it=myData.begin();it!=myData.end();it++)
{
  do_poly(it->second); //do_poly call the function from map
}
  • Please include the relevant code in your answer, so that it remains useful even if the external link breaks. – doldt Sep 24 '16 at 17:54