Sign in to follow this  
kohma

[C++] no contextual type information in my code, need help

Recommended Posts

Hi, I'm programming a lua-to-c++ library, but more for myself and fun. In it I work a lot with partial template specializations and non-type template arguments. Right now I get an error msg like "test.cpp:51: error: address of overloaded function with no contextual type information". Maybe somebody could help me on unterstanding why the code fails. At the end you find a copy&compileable stripped down version of my code. I would really appreciate any help or ideas :)
#include <iostream>
#include <vector>

using namespace std;
typedef vector<int> vec;
typedef vec::reference tref;
typedef vec::size_type tsize;

template<typename T, T* P>
struct FunWrapper {
};

template<typename T, T P>
struct MemFunWrapper {
};

template<typename tRet,typename A1,tRet (*func)(A1)>
struct FunWrapper<tRet(A1),func> {
  static void foo() { cout<<"Fun Wrap"<<endl; }
};

template<class C,typename tRet,typename A1,tRet (C::*memFunc)(A1)>
struct MemFunWrapper<tRet(C::*)(A1),memFunc>{
  static void foo() { cout<<"Mem Fun Wrap"<<endl; }
};

template<typename T,T* P>
void reg() {
  FunWrapper<T,P>::foo();
}

template<typename T,T P>
void reg() {
  MemFunWrapper<T,P>::foo();
}

template<typename T,T P>
void reg_mf() {
  MemFunWrapper<T,P>::foo();
}

int main() {
  /* on gcc 4.1.1 the following line gives me                                                                                                                      
     test.cpp:51: error: address of overloaded function with no contextual type information                                                                        
                                                                                                                                                                   
     if you comment out the FunWrapper<tRet(A1),func> specialization it works as well                                                                              
  */
  //reg<tref(vec::*)(tsize),&vec::at>();                                                                                                                           

  /* this version works */
  reg_mf<tref(vec::*)(tsize),&vec::at>();
  return 0;
}

Share this post


Link to post
Share on other sites
vec::at() is actually two different functions const int & vec::at(size_type) const and int & vec::at(size_type). What the error message is telling you is that it can't figure out which one you mean. You can disambiguate it with a cast.

Share this post


Link to post
Share on other sites
Sorry, but I don't understand what you mean.

Even though I know it wouldn't work I tried:
 reg<tref(vec::*)(tsize),static_cast<tref(vec::*)(tsize)>(vec::at)>(); 


One cannot cast something in the template parameter list. More specifically my compiler complains "a cast to a type other than an integral or enumeration type cannot appear in a constant-expression".

But this wasn't probably what you meant by casting. Also it's weird that if I comment the one specialization out (see the source), the compiler doesn't complain. Even though the specialization wasn't for member function pointers but for normal function pointers.

Could you please be a little bit more verbose?

Share this post


Link to post
Share on other sites
I've redone my example code and I narrowed down the problem. Probably I get some more responses now :)


/* takes function type as first template parameter */
/* and a function pointer of the function type as */
/* the second template parameter */
template<typename T,T* P>
void reg() { }

/* takes member function type as first template */
/* parameter and member function pointer of the type */
/* as second template parameter */
template<typename T,T P>
void reg() { }

template<typename T,T P>
void reg_mf() { }

struct T_at_atconst {
int at(int) { }
const int at(int) const { }
};

int main() {
/* the compiler only can't cope with the normal and */
/* the const version of the member function */
/* if there are two versions of the template function */
/* one which accepts function pointers and one which */
/* accepts member function pointers */
/* but actually the memFun type should be clear since */
/* I have to give as the first template parameter */

/* so this works and the compiler can deduce which */
/* version of the member function should be used */
reg_mf<int(T_at_atconst::*)(int),&T_at_atconst::at>();
reg_mf<const int(T_at_atconst::*)(int)const,&T_at_atconst::at>();

/* but this won't work, why? */
//reg<int(T_at_atconst::*)(int),&T_at_atconst::at>();
//reg<const int(T_at_atconst::*)(int)const,&T_at_atconst::at>();

return 0;
}



I cannot explain this odd behaviour. Maybe somebody can explain. Maybe it's explained in the standard or it's just a flaw of my compiler.

Thanks in advance :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this