Function pointer as template argument - does not work for function template

A

avasilev

HI all,
Can anyone tell me why this c ode does not compile on MSVC2008, but
compiles fine with GCC4. Are there any differences related to function
pointer template arguments for class templates and func templates?

template <typename Sig>
struct FuncSig;

template<typename RV, typename A1>
struct FuncSig<RV(A1)>
{ typedef RV(*Type)(A1); };

//Class template with the help of the signature class
template <typename Sig, typename FuncSig<Sig>::Type Func>
class Test{};

//function template with the help of the signature class
template <typename Sig, typename FuncSig<Sig>::Type Func>
int TestFunc()
{ return 123; }

//some random fucntion to pass as a pointer
int func(char a)
{
return 5;
}

Test<int(char), &func> f; //compiles as expected

int main()
{

//compiles on GCC, but fails on MSVC2008, with error messge:
//templateFuncAndClassArgValidity.cpp(27) : error C2975: 'Func' :
invalid template argument for //'TestFunc', expected compile-time
constant expression
// templateFuncAndClassArgValidity.cpp(13) : see declaration of
'Func'

TestFunc<int(char), &func>();
}
 
V

Victor Bazarov

template<typename Sig>
struct FuncSig;

template<typename RV, typename A1>
struct FuncSig<RV(A1)>
{ typedef RV(*Type)(A1); };

//Class template with the help of the signature class
template<typename Sig, typename FuncSig<Sig>::Type Func>
class Test{};

//function template with the help of the signature class
template<typename Sig, typename FuncSig<Sig>::Type Func>
int TestFunc()
{ return 123; }

//some random fucntion to pass as a pointer
int func(char a)
{
return 5;
}

Test<int(char),&func> f; //compiles as expected

int main()
{

//compiles on GCC, but fails on MSVC2008, with error messge:
//templateFuncAndClassArgValidity.cpp(27) : error C2975: 'Func' :
invalid template argument for //'TestFunc', expected compile-time
constant expression
// templateFuncAndClassArgValidity.cpp(13) : see declaration of
'Func'

TestFunc<int(char),&func>();
}

Most likely it's a bug in VC2008 (still exists in VC2010). A pointer to
a function is allowed to be used as a non-type template argument if the
function has external linkage (as your 'func' apparently does). See
[temp.arg.nontype]/1, third bullet.

V
 
M

Marcel Müller

//compiles on GCC, but fails on MSVC2008, with error messge:
//templateFuncAndClassArgValidity.cpp(27) : error C2975: 'Func' :
invalid template argument for //'TestFunc', expected compile-time
constant expression
// templateFuncAndClassArgValidity.cpp(13) : see declaration of
'Func'

TestFunc<int(char),&func>();
}

Most likely it's a bug in VC2008 (still exists in VC2010). A pointer to
a function is allowed to be used as a non-type template argument if the
function has external linkage (as your 'func' apparently does). See
[temp.arg.nontype]/1, third bullet.

I remember a similar bug in VS2003. AFAIR you can't use any linker
symbols as template arguments. I had a smart pointer class, that used a
singleton in case a NULL value is dereferenced. The singleton is passed
as template argument.

There was a work-around, maybe it helps here too. Define a constant that
is inilialized to your function pointer and use this one as template
argument.


Marcel
 
A

avasilev

Interestingly, though, this compiles (on both compilers):

template <typename Sig>
struct FuncSig;

template<typename RV, typename A1>
struct FuncSig<RV(A1)>
{ typedef RV(*Type)(A1); };

template <class C, typename Sig>
struct MethodSig;

template<class C, typename RV, typename A1>
struct MethodSig<C, RV(A1)>
{ typedef RV(C::*Type)(A1); };

//Class template with the help of the signature class
template <typename Sig, typename FuncSig<Sig>::Type Func>
class Test{};

//Class template with the help of the signature class
template <class C, typename Sig, typename MethodSig<C, Sig>::Type
Method>
class TestM{};

//function template with the help of the signature class
template <typename Sig, typename FuncSig<Sig>::Type Func>
int TestFunc()
{ return 123; }

//function template with the help of the signature class
template <class C, typename Sig, typename MethodSig<C, Sig>::Type
Method>
int TestFuncM()
{ return 123; }

//some random fucntion to pass as a pointer
int func(char a)
{
return 5;
}

struct MyClass
{ int method(char a) {return 5;} };

Test<int(char), &func> f; //compiles as expected
TestM<MyClass, int(char), &MyClass::method> m;

int main()
{
TestFuncM<MyClass, int(char), &MyClass::method>();
}
 
A

avasilev

I remember a similar bug in VS2003. AFAIR you can't use any linker
symbols as template arguments. I had a smart pointer class, that used a
singleton in case a NULL value is dereferenced. The singleton is passed
as template argument.

There was a work-around, maybe it helps here too. Define a constant that
is inilialized to your function pointer and use this one as template
argument.

It seems this is not the problem - I can do it freely with class
templates, but not with function templates. In the second example I
posted, it works with a func template class as well, but only with a
method signature.
In your case, did you try to pass NULL as a template func pointer
argument? If so, the case is different, I also have tried to do it,
but the pre-C++0x standard prohibits this explicitly
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,961
Messages
2,570,130
Members
46,689
Latest member
liammiller

Latest Threads

Top