By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,245 Members | 884 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,245 IT Pros & Developers. It's quick & easy.

Compiler error - incorrect error message "illegal type for non-type template parameter"

P: n/a
The code below does not compile with .NET 2003, I get folowing error:

w:\c\Pokusy\delegTemplArg\delegTemplArg.cpp(11) : error C2993: 'float' :
illegal type for non-type template parameter 'x'

The error shows compiler is quite confused - x is not a template parameter
at all.

I have found two workarounds, but still I think the code should compile.

Workaround 1: declare member RetType (Type::*member)(float x) const using a
typedef:
typedef RetType (Type::*DelegateFunctionType)(float x) const;
template <class Type, class RetType, DelegateFunctionType>

Workaround 2: ommit the parametr name in the member function prototype:
template <class Type, class RetType, RetType (Type::*member)(float)
const>

Regards
Ondrej
--------------------------------
#include <stdio.h>

class FooA
{
public:
float GetValue1(float x) const {return 1;}
float GetValue2(float x) const {return 2;}
};

/// delegate - member passed via template argument
template <class Type, class RetType, RetType (Type::*member)(float x) const>
class DelegateTF
{
Type &_type;
public:
DelegateTF(Type &type):_type(type){}
RetType operator () (float x) const
{
return (_type.*member)(x);
}
};

int main()
{
FooA a;
DelegateTF<FooA,float,FooA::GetValue2> atd2(a);
printf("atd2 %g\n",atd2(0.5));
getchar();
return 0;
}
Nov 17 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Thanks Ondrej,
I have verified that this is a bug with our compiler and have logged it in
our database. Hopefully it will be fixed for whidbey .
Your workarounds still work fine with the recent compilers.
Regards,
Kapil

"Ondrej Spanel" <on***********@bistudionospam.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
The code below does not compile with .NET 2003, I get folowing error:

w:\c\Pokusy\delegTemplArg\delegTemplArg.cpp(11) : error C2993: 'float'
: illegal type for non-type template parameter 'x'

The error shows compiler is quite confused - x is not a template parameter
at all.

I have found two workarounds, but still I think the code should compile.

Workaround 1: declare member RetType (Type::*member)(float x) const using
a typedef:
typedef RetType (Type::*DelegateFunctionType)(float x) const;
template <class Type, class RetType, DelegateFunctionType>

Workaround 2: ommit the parametr name in the member function prototype:
template <class Type, class RetType, RetType (Type::*member)(float)
const>

Regards
Ondrej
--------------------------------
#include <stdio.h>

class FooA
{
public:
float GetValue1(float x) const {return 1;}
float GetValue2(float x) const {return 2;}
};

/// delegate - member passed via template argument
template <class Type, class RetType, RetType (Type::*member)(float x)
const>
class DelegateTF
{
Type &_type;
public:
DelegateTF(Type &type):_type(type){}
RetType operator () (float x) const
{
return (_type.*member)(x);
}
};

int main()
{
FooA a;
DelegateTF<FooA,float,FooA::GetValue2> atd2(a);
printf("atd2 %g\n",atd2(0.5));
getchar();
return 0;
}

Nov 17 '05 #2

P: n/a
Hi !

Like Ondrej already stated, it's a bug.

However, the workaround 2 seems to like a "standard legit" way to do this. I
have rarely seen that a pointer-to-function or pointer-to-member would
specify parameter names. For example:

int (ClassA::*ptrFunc)(float, int, int) = &AObj::Func1;

or

int (*ptrFunc)(float, int, int) = &Func1;

Neither has parameter names specified. In light of this, a template
declaration of

template<class A, typename RetVal, RetVal (A::*pFunc)(float,int,int)>

seems valid and correct.

If pFunc above would have parameter names specified, would it change
anything ? It's nice to know that it'll be fixed, although I can't quite
understand why :)

If someone knows if there is a difference, I'd be happy to know.

-Antti Keskinen
"Ondrej Spanel" <on***********@bistudionospam.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
The code below does not compile with .NET 2003, I get folowing error:

w:\c\Pokusy\delegTemplArg\delegTemplArg.cpp(11) : error C2993: 'float'
: illegal type for non-type template parameter 'x'

The error shows compiler is quite confused - x is not a template parameter
at all.

I have found two workarounds, but still I think the code should compile.

Workaround 1: declare member RetType (Type::*member)(float x) const using
a typedef:
typedef RetType (Type::*DelegateFunctionType)(float x) const;
template <class Type, class RetType, DelegateFunctionType>

Workaround 2: ommit the parametr name in the member function prototype:
template <class Type, class RetType, RetType (Type::*member)(float)
const>

Regards
Ondrej
--------------------------------
#include <stdio.h>

class FooA
{
public:
float GetValue1(float x) const {return 1;}
float GetValue2(float x) const {return 2;}
};

/// delegate - member passed via template argument
template <class Type, class RetType, RetType (Type::*member)(float x)
const>
class DelegateTF
{
Type &_type;
public:
DelegateTF(Type &type):_type(type){}
RetType operator () (float x) const
{
return (_type.*member)(x);
}
};

int main()
{
FooA a;
DelegateTF<FooA,float,FooA::GetValue2> atd2(a);
printf("atd2 %g\n",atd2(0.5));
getchar();
return 0;
}

Nov 17 '05 #3

P: n/a
Ondrej Spanel wrote:
The code below does not compile with .NET 2003, I get folowing error:

w:\c\Pokusy\delegTemplArg\delegTemplArg.cpp(11) : error C2993:
'float' : illegal type for non-type template parameter 'x'

The error shows compiler is quite confused - x is not a template
parameter at all.

I have found two workarounds, but still I think the code should
compile.
Yes, it should, as has been noted previously. The formal parameter name
('x') is no different than a parameter name in a function prototype - it
serves no purpose other than documentation but is legal.
int main()
{
FooA a;
DelegateTF<FooA,float,FooA::GetValue2> atd2(a);
This is non-standard and should not compile (VC allows it as an extension
unless you compile with /Za). It should read

DelegateTF<FooA,float,&FooA::GetValue2> atd2(a);
printf("atd2 %g\n",atd2(0.5));
getchar();
return 0;
}


Thanks for posting a complete repro case! So few people do.

-cd
Nov 17 '05 #4

P: n/a
> If pFunc above would have parameter names specified, would it change
anything ? It's nice to know that it'll be fixed, although I can't quite
understand why :)

If someone knows if there is a difference, I'd be happy to know.


There is no difference other than different code clarity. Parameter names
can improve readability of the code.

It is not a serious bug, given there is an easy workaround, but still I am
glad it will be fixed - thanks to MS compiler team. Writing template code is
hard enough in itself, and when you get a cryptic error messages like this
during development, it makes it even harder. I am very glad to see the
quality of template support in VC++ gets much better with each release - it
is already a huge improvement over VC++6.

Regards
Ondrej
Nov 17 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.