Member_2_3519
asked on
Template member function in non template class
Should this code be valid in VC++ 6?
class testc
{
public:
template <class TTYPE>
void dosomething(TTYPE var)
{
cout << var << endl;
}
};
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
...
UINT ui1;
WORD w1;
testc c;
ui1 = 123;
w1 = 99;
c.dosomething<UINT>(ui1); // error C2275: 'UINT' : illegal use of this type as an expression
c.dosomething<WORD>(w1); // error C2275: 'WORD' : illegal use of this type as an expression
...
}
I get the shown error messages. What is wrong?
class testc
{
public:
template <class TTYPE>
void dosomething(TTYPE var)
{
cout << var << endl;
}
};
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
...
UINT ui1;
WORD w1;
testc c;
ui1 = 123;
w1 = 99;
c.dosomething<UINT>(ui1); // error C2275: 'UINT' : illegal use of this type as an expression
c.dosomething<WORD>(w1); // error C2275: 'WORD' : illegal use of this type as an expression
...
}
I get the shown error messages. What is wrong?
Hi MSi,
sorry, AlexFM, but it compiles fine (and even works :) on my VC++ 6.0 ...
it's nearly correct ... just leave out the types at the function call (since the type is already given by the parameter), i.e.
c.dosomething(ui1);
c.dosomething(w1);
You can check that it's called for different types if you turn on RTTI and let 'dosomething' print out the typename, i.e.:
std::cout << typeid( var ).name() << ": " << var << std::endl;
hope that helps,
ZOPPO
sorry, AlexFM, but it compiles fine (and even works :) on my VC++ 6.0 ...
it's nearly correct ... just leave out the types at the function call (since the type is already given by the parameter), i.e.
c.dosomething(ui1);
c.dosomething(w1);
You can check that it's called for different types if you turn on RTTI and let 'dosomething' print out the typename, i.e.:
std::cout << typeid( var ).name() << ": " << var << std::endl;
hope that helps,
ZOPPO
By the way, when I tried to make template function as static class function, I got internal compiler error.
Nice. You are right.
It is as simple as using
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
UINT ui1;
WORD w1;
testc c;
ui1 = 123;
w1 = 99;
c.dosomething(ui1);
c.dosomething(w1);
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
UINT ui1;
WORD w1;
testc c;
ui1 = 123;
w1 = 99;
c.dosomething(ui1);
c.dosomething(w1);
}
BTW, I tested the above with VC6
ASKER
ok, that sample compiles. But in my working project I get the following error message:
G:\source\Script\Proxy_Dev ice.cpp(30 45) : error C2893: Failed to specialize function template 'unsigned char __thiscall CProxy_Device::ReadResourc e1(ADDRHAN DLERTYPE,u nsigned int)'
With the following template arguments:
'class CEEAddrHandler'
G:\source\Script\Proxy_Dev
With the following template arguments:
'class CEEAddrHandler'
hm ... could you show the declaration and implementation of ReadResource1 and how it's called?
BTW, MSDN only tells about error C2893 that 'There can be many causes for this error. Try changing
your source code to specialize the function template in a different way.' ... so, I think we need more
information ...
ZOPPO
BTW, MSDN only tells about error C2893 that 'There can be many causes for this error. Try changing
your source code to specialize the function template in a different way.' ... so, I think we need more
information ...
ZOPPO
If the template TYPE is the return type of the member function, then this will not work in VC++ 6.0.
For example, the following class will fail to work with VC++ 6.0
class testc
{
public:
template <class TTYPE>
TTYPE dosomething(void)
{
return TTYPE();
}
};
For example, the following class will fail to work with VC++ 6.0
class testc
{
public:
template <class TTYPE>
TTYPE dosomething(void)
{
return TTYPE();
}
};
ASKER
Declaration is like following:
class xxx
{
...
protected:
template<class ADDRHANDLERTYPE>
BYTE ReadResource1(ADDRHANDLERT YPE AddressHandler, UINT ErrID);
}
call is like this:
void xxx::anyfunction()
{
...
CAddrHandler *handler;
BYTE dstat;
handler = g_DevPtr->GetAddressHandle r();
dstat = ReadResource1(handler, IDS_ERR_UNKNOWN_ADDRESS);
...
}
class xxx
{
...
protected:
template<class ADDRHANDLERTYPE>
BYTE ReadResource1(ADDRHANDLERT
}
call is like this:
void xxx::anyfunction()
{
...
CAddrHandler *handler;
BYTE dstat;
handler = g_DevPtr->GetAddressHandle
dstat = ReadResource1(handler, IDS_ERR_UNKNOWN_ADDRESS);
...
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Right. Or after class declaration in the same h-file, with inline keyword.
ASKER
Thank you Axter,
it really works only, if the function implementation is inside the class declaration...
it really works only, if the function implementation is inside the class declaration...
Hmm, don't want to criticise you, but your original Q was clearly answered by Zoppo...
Wow ... it's impressing to see that still people take care of good habits at EE ... great!
I gave up blaming people when I think their grading wasn't correct since
1. IMO it didn't help anything and I didn't like to get unkind ...
2. I mostly feel wasting time for answering questions is enough, no need to waste more for discussing the grading ...
Thanks for your comment, jkr, this simple sentence really raised my today's mood ...
regards,
ZOPPO
I gave up blaming people when I think their grading wasn't correct since
1. IMO it didn't help anything and I didn't like to get unkind ...
2. I mostly feel wasting time for answering questions is enough, no need to waste more for discussing the grading ...
Thanks for your comment, jkr, this simple sentence really raised my today's mood ...
regards,
ZOPPO
ASKER
Sorry,
but I cannot find the comment from Zoppo, where he tells me to put the implentation inside of the class declaration.
but I cannot find the comment from Zoppo, where he tells me to put the implentation inside of the class declaration.
ASKER
Ok, sorry. I think I forgot the original Q since it did not resolves my original problem.
Is there any way to give Zoppo points? I would be glad to give 1000 extra points for my mistake from my account.
Is there any way to give Zoppo points? I would be glad to give 1000 extra points for my mistake from my account.
No need to give so much points ... in fact I don't really care points ... it's just a matter of principle: Some people (i.e. like me) investigate time here to help other people (i.e. like you) for nothing than appreciation and maybe points ... and, I swear you, my time is not really cheap ;-) ... I do it coz like to do this generally ... and, if I am treated well I'll continue doing so :)
Maybe next time you better think about your question's subject and sample code ...
If you still think you want to give me some points you can post a question like 'Points for Zoppo' and set the number of points you wanna give ...
regards,
ZOPPO
Maybe next time you better think about your question's subject and sample code ...
If you still think you want to give me some points you can post a question like 'Points for Zoppo' and set the number of points you wanna give ...
regards,
ZOPPO
ASKER
ok, I'll do
>>but I cannot find the comment from Zoppo, where he tells me to put the
>>implentation inside of the class declaration
So, can you find the comment from Axter where he wrote
just leave out the types at the function call (since the type is already given by the parameter), i.e.
c.dosomething(ui1);
c.dosomething(w1);
?
Without that, putting the implementation inside the declaration would still not have helped. Usually, on an issue like this, you'd split the points between Zoppo and Axter.
>>implentation inside of the class declaration
So, can you find the comment from Axter where he wrote
just leave out the types at the function call (since the type is already given by the parameter), i.e.
c.dosomething(ui1);
c.dosomething(w1);
?
Without that, putting the implementation inside the declaration would still not have helped. Usually, on an issue like this, you'd split the points between Zoppo and Axter.
yes, I agree completely with jkr ...
ASKER
So, I have created a new question with points for Zoppo, so both have points.
1) Make template for the whole class:
template <class TTYPE>
class testc
{
public:
void dosomething(TTYPE var);
}
2) Use overloading:
class testc
{
public:
void dosomething(UINT var);
void dosomething(WORD var);
};
3) Make template function global passing class instance to it:
class testc
{
};
template <class TTYPE>
void dosomething(TTYPE var, testc* pTest)
{
cout << var << endl;
// use here pTest to access testc members and functions
}
int main(int argc, char* argv[])
{
UINT ui1;
WORD w1;
testc c;
ui1 = 123;
w1 = 99;
dosomething<UINT>(ui1, &c);
dosomething<WORD>(w1, &c);
return 0;
}