language >> BUG: template pointer to function

by Mycroft Holmes » Mon, 12 Jan 2004 20:56:04 GMT

Hi to all,

I've come across this bug in VC7.1
rpn_c is a wrapper for pointers to functions taking several arguments




template <typename function_t>
struct rpn_c;


template <typename T>
struct rpn_c< T (*)(const T&, const T&) >
{
typedef T (*f_t)(const T&, const T&);

template <f_t F>
static T eval(const T* x)
{
return F(x[0],x[1]);
}

};




int ran2(const int&,const int&)
{
return 5;
}



int main()
{
int a[2] = {4, 5};
int* aa =a;

typedef int (*ifunc)(const int&,const int&);

// runtime assignemnt succeeds
rpn_c<ifunc>::f_t F = ran2;

// compile-time evaluation does not work
int i = rpn_c<ifunc>::eval<ran2>(aa);

return 0;
}













--
A problem is a problem is a problem
A solution is a solution.
-- Mycroft Holmes





Similar Threads

1. BUG: template pointer to function (full message)

Hi to all,

    I've come across this bug in VC7.1
rpn_c is a wrapper for pointers to functions of the form

T f(const T&, ... , const T& ).

here I list only the partial specialization for 2 arguments, but we have
many more.
the idea is: we have a library of functions taking N (say, at most 8)
arguments of the same type but we want to provide them packed in an array,
so we need a wrapper taking ANY pointer to function (known at compile time!)
which adapts the interface.

VC7.1 does not compile the following code, which indeed looks correct (btw
Comeau and Intel 8.0 do accept it):



//// version 1: begin ////////////

template <typename function_t>
struct rpn_c;


template <typename T>
struct rpn_c< T (*)(const T&, const T&) >
{
 typedef T (*f_t)(const T&, const T&);

 template <f_t F>
  static T eval(const T* x)
 {
  return F(x[0],x[1]);
 }

};




int ran2(const int&,const int&)
{
 return 5;
}



int main()
{
 int a[2] = {4, 5};
 int* aa =a;

 typedef int (*ifunc)(const int&,const int&);

// runtime assignemnt succeeds
 rpn_c<ifunc>::f_t F = ran2;

// compile-time evaluation does not work
 int i = rpn_c<ifunc>::eval<ran2>(aa);

 return 0;
}


//// version 1: end ////////////


more surprisingly, VC7.1 does accept the following variation:



//// version 2: begin ////////////

template <typename function_t, function_t f>
struct rpn_c;


template <typename T, T (*F)(const T&, const T&) >
struct rpn_c< T (*)(const T&, const T&), F >
{
 typedef T (*f_t)(const T&, const T&);

 static T eval(const T* x)
 {
  return F(x[0],x[1]);
 }

};



int ran2(const int&,const int&)
{
 return 5;
}



int main()
{
 int a[2] = {4, 5};
 int* aa =a;

 typedef int (*ifunc)(const int&,const int&);

 int i = rpn_c<ifunc, ran2>::eval(aa);

 return 0;
}


//// version 2: end ////////////


I said 'surprisingly' because Intel 8.0 rejects the code with obscure
errors, and Comeau online gives the following message:


Comeau C/C++ 4.3.3 (Aug  6 2003 15:13:37) for ONLINE_EVALUATION_BETA1
Copyright 1988-2003 Comeau Computing.  All rights reserved.
MODE:strict errors C++

"ComeauTest.c", line 5: error: the type of partial specialization template
          parameter constant "F" depends on another template parameter
  template <typename T, T (*F)(const T&, const T&) >



I don't know if this is forbidden by the standard, but for sure a compiler
CAN match two parameters with this partial specialization (easy proof: see
VC7.1!)


Anyway, I'm very interested in a workaround which is compiled by both ICL
and VC (I wrote a couple of #ifdef's but I don't like them...)

Thanks in advance for any idea

-- 
 A problem is a problem is a problem
 A solution is a solution.
-- Mycroft Holmes




2. Passing pointer to template function as argument to pointer to template function

3. Template specialization of pointers with function pointers

Ok, I have a template function for any pointer to type T:

template <typename T>
void func(T* p)
{
    DoSomethingGeneric(p);
}

Can I specialize this template for pointers to functions (or pointers
to member functions, or pointers to anything)? I would like to do
something like this:

typedef void (*FUNCPTR)();

template <>
void func(FUNCPTR p)
{
    DoSomethingSpecialWithFuncPtr(p);
}

but my compiler (Visual C++ 6) won't let me. I know VC6 is lacking in
support for templates, but I'd like to know if this is even legal
anyway. Thanks.

4. Pointers to member function templates as template arguments

5. Function Templates with function Pointers ( ...)

Hi

I have bugs with basic function templates.
I folowed a documentation on MSDN, and it still wont compile
Is this a VC6 bug ?

I figured out on my own that templates do not compile the same
within the scope of a class then on their own :

This compile fine:

 long getlong()
 {
  return 123L;
 }

 template <class RT>
 RT templatefunction(RT (*f)())
 {
  return (*f)();
 }

 void docall()
 {
  long l = templatefunction<long>(getlong);
 }


///////////////////////////////////////////////

This did not compile :

class CA
{
public:

 CA(){}
 ~CA(){}

 long getlong()
 {
  return 123L;
 }

 template <class RT>
 RT templatefunction(RT (*f)())
 {
  return (*f)();
 }

 void docall()
 {
  long l = templatefunction<long>(getlong);
 }

};

Its the exact same code for template calls expect its inside a class.
This is also why i have been having tons of compile errors.

I wish i could find ONLINE info on this, so i can be productive.
Thanks for suggesting a book i know id have to wait about
10 days to receive, but id rather a online reference to an explanation
if thats at all possible...

thanks














6. Function pointers & template functions

7. Is it legal to assign a template function to a function pointer this way

I was looking at some code in the MS NG, and I saw this code listed.
template <class T>class List{};

template<class T>
bool MySortFunc(List<T>& list){return true;}

template <class T>struct SORT{typedef bool (*FnPtr)(List<T>& list);};

int main(){
	List<int> MyList;
	List<long> MyList2;
	SORT<int>::FnPtr Sort = &MySortFunc; //***No template type!!!!!!!
	Sort(MyList);

I would think that the function pointer assignment would not compile
with out using the templae type.
SORT<int>::FnPtr Sort = &MySortFunc<int>;

But I was able to compile this with out the type on both VC++ and
Comeau.

So is this code legal, or are the compilers wrong to compile it
successfully?

8. generic classes template function with function pointer and argument number overloading (lol)