0

I have been hitting my head against a brick wall for a bit and decided to submit and just post my error.

I have a template (shown below) that passes a std::map, which is inside a namespace. This compiles fine.

My problem occurs when trying to call the function template. I get the below error:

error: no matching function for call to 
    'getValuePointer(Muon*&, std::map<int, MET*, std::less<int>, 
                     std::allocator<std::pair<const int, MET*> > >*&)'

What am I doing wrong?

Here is the template code:

#ifndef OBJECTMAPMATCH_H
#define OBJECTMAPMATCH_H

#include <map>
#include <utility>
#include <typeinfo>
#include <iostream>
#include <stdlib.h>

using namespace std;

namespace ObjectMapMatch {


  template< class A, class B, class C >
    C  getValuePointer( A &x , map< B,C> &y )
  {

    if( y.find(x.Index()) != y.end() ){

      return y.find(x.Index()).second;

    }else{
      cout << "ERROR:ObjectMapMatch::getValuePointer:Can not Find " 
           <<  typeid(y).name() << " FOR " << typeid(x).name() << endl;
      exit(1);
    }

  }

}
#endif

Here is an example call to the template function

C = ObjectMapMatch::getValuePointer<ClassC*, int, ClassD*>(A, B);

Where:

C is ClassC*
A is ClassC*
B is std::map<int,ClassD*>*  

What am I doing wrong?

MWright
  • 1,681
  • 3
  • 19
  • 31
  • I constructed a [similar example](http://ideone.com/Relqo), and it runs fine. – Björn Pollex Nov 30 '11 at 14:30
  • 1
    Not a solution, but just a helpful note - unless I'm mistaken, you can use what's called "template type inference" in this case and simplify your function call to `C = ObjectMapMatch::getValuePointer(A, B);`. The types `` will be inferred automatically – Nate Nov 30 '11 at 14:32
  • I would add to Nate, that you not just can, but *SHOULD* use template type inference (applies to function templates only, of course). – Jan Hudec Nov 30 '11 at 14:36
  • 1
    The fact that you use A,B,C with two completely different meanings here, and that you use different class names for the same thing (e.g. Muon and ClassC) makes this question a lot more confusing than it should be. – interjay Nov 30 '11 at 14:41
  • @interjay Yes That was stupid of me. Would edit but the answers would then not make sense. – MWright Nov 30 '11 at 14:50

4 Answers4

3

According to the error message, you passed a pointer to a map as the second parameter, while the function expects a reference to a map.

You can see this because of the * at the end here:

no matching function for call to 
    'getValuePointer(Muon*&, std::map<...>*&)'
                                          ^

There will be additional issues once you fix this though: Since x is of type ClassC*, calling x.Index() will give an error. Maybe the first template parameter should be ClassC instead of ClassC*.

interjay
  • 107,303
  • 21
  • 270
  • 254
  • A more to-the-point way of saying this is that `B` should not be declared as a pointer. – Nate Nov 30 '11 at 14:37
  • @Nate: True, but originally the question said that B wasn't a pointer (which was obviously false). It has been edited now. – interjay Nov 30 '11 at 14:41
  • You sir are absolutely right. Don't know how I missed that. +1 all the same. – Nate Nov 30 '11 at 14:46
0

Your template definition says:

 C  getValuePointer( A &x , map< B,C> &y )

And you are calling this function with:

ObjectMapMatch::getValuePointer<ClassC*, int, ClassD*>(A, B);

... and you say that B is:

std::map<int,ClassD*>

So, for your template B is an int, and C is a ClassD*... That's why there is not a match.

Or maybe not, I mean, the name you chose for the values is the same for the classes in your template, which is quite confusing.

Hope this helps.

Baltasarq
  • 12,014
  • 3
  • 38
  • 57
0

your signature is wrong

template< class A, class B, class C >
C* getValuePointer( A* x , map<B, C*> &y )
{
    if( y.find(x->Index()) != y.end() ){
        return y.find(x->Index()).second;
    }else{
        cout << "ERROR:ObjectMapMatch::getValuePointer:Can not Find " 
             <<  typeid(y).name() << " FOR " << typeid(x).name() << endl;
        exit(1);
    }
}

and the call it

ObjectMapMatch::getValuePointer<ClassC, int, ClassD>(A, B);

but C is ClassD*, not ClassC* right?

esskar
  • 10,638
  • 3
  • 36
  • 57
0

In your last edit you say that

B is std::map<int,ClassD*>*

but your function is

template< class A, class B, class C >
C  getValuePointer( A &x , map< B,C> &y )

thus accepting

std::map<int,ClassD*> &

for the second argument. So pointer to map vs. reference to map. I suppose you should either be passing *B, or B should not be pointer (STL is there so you don't need to work with pointers much so try avoiding them as much as possible).

Jan Hudec
  • 73,652
  • 13
  • 125
  • 172