how can i make template method of specified class ?? I saw some tutorials on this topic but they just made whole class template, so they had to specify what type the template will reffer to.
Posted on 2005-06-11 14:15:51 by AceEmbler
class MyClass
{
? ...
? template<class R, class P1, class P2>
? R template_member(P1 p1, P2 p2) { ... };
? ...
};



but they just made whole class template, so they had to specify what type the template will reffer to.


Depending on the context, there are some chances you'll have to specify the template specialization explicitly as well.


BTW, what do you intend to achieve? I'm asking this because I never ran into a case that needed this construct (I always end up using template classes rather than template members), so I'm curious about the practical uses. :|
Posted on 2005-06-11 16:30:43 by chep
Im trying to make something like V'kim's ddebuggerbut for win32 c++. I'm using richedit for this.And i have got PrintTable Method which is going to print array of specified types. So user can print int,char,float and so on using the same method. I made it before just like you have shown. But it is not compiling  Visual Studio 6.0 returns this error

unresolved external symbol "public: void __thiscall ErrorHandle::PrintTable(char *,int *,int,bool)" (?PrintTable@ErrorHandle@@QAEXPADPAHH_N@Z)

here is a piece of code, maybe I'm doing something wrong.

Class Declaration:

class ErrorHandle 
{
public:
ErrorHandle();
ErrorHandle(char *Name,HINSTANCE hInst,LPCTSTR DialogID,HWND hWndParent,DLGPROC WProc);
virtual ~ErrorHandle();
void MsgBox(char *Caption,char *Error);
void ClearText();
int GetTextLength();
void AddText(char *Text);
void AddText(char *Text,int Nr);
void AddText(char *Text,int Nr,char System);
void AddText(char *Text,float Nr);
void AddText(char *Text,double Nr);
template<class _T> void PrintTable(char *Str,_T *Items,int ICount,bool Position);

public:
HWND m_hDialog;
HWND m_hRichEdit;


private:
bool NLine;
char m_Buffer[256];
CHARFORMAT m_sCharFormat;
char m_szText[256];
};


this not working method:

template<class _T> void ErrorHandle::PrintTable(char *Str,_T *Items,int ICount,bool Position)
{
AddText(Str);
AddText("\nPrintTable Begin\n");
NLine=0;
if (Position==0)
{
for (int i=0;i<ICount;++i)
{
AddText("",*(Items++));
}
}
else
{

}
NLine=1;
AddText("\nPrintTable End\n");

}


here is the call:

i=22;
ErrorH->AddText("klopsy\n");
ErrorH->AddText("siudemka ",7);
ErrorH->AddText("LiczBA 3 w binarze to",3,2);
ErrorH->AddText("Liczba float ===",(float)9.23456);
ErrorH->AddText("Liczba float ===",(double)9.23456);
ErrorH->PrintTable("huh",(int*)&i,1,0);
Posted on 2005-06-11 17:00:17 by AceEmbler
At first glance your code looks right...

So you're using VS6 ?!
By chance, aren't you building your project in Debug mode ? If so, try building it in Release mode. VS6 is known to have problems with templates in Debug mode (I guess this has something to do with some "Don't inline in Debug mode" flag, but I can't tell you more as I don't really master VS6).
Well, anyway, VS6 is known to have problems with *templates*. :sad:

You could try overloading your PrintTable method (just like the AddText method), which at final would generate no more code than the template way, but it would surely solve your problem.
As far as I have heard of it, using templates with VS6 is plain Evil, and it's the best way to run into problems !
Posted on 2005-06-11 17:20:57 by chep
It's the same with release mode. I don't want to overload functions with the same code inside, plus I'm not to familiar with templates an i wanted to practice with it a little. BTW i thought that VS is the best IDE for win32 C++ out there, Can you point me to something better ??
Posted on 2005-06-11 17:29:21 by AceEmbler
OK i have solved this problem.But it's like "oh my God" for me and my clean code. I will consider it as  a bug in visual studio.

it looks like template methods definition have to be  inside class declaration.


class
{

template<class _type> function(_type var){And all this meat here};

}

Posted on 2005-06-11 17:53:37 by AceEmbler

BTW i thought that VS is the best IDE for win32 C++ out there, Can you point me to something better ??


Sure, VC is the best *compiler* out there. But IMHO, Borland's C++Builder is the best *IDE*. The problem is that, even if Borland's compiler is far quicker than MS's one, the resulting code quality is poorer, plus it is not binary compatible with VC. So I advise you to stick with VS after all. :P

VC7 (.NET) is far less buggy than VC6.
Microsoft is offering the VC7.1 compiler as a free download (Visual C++ Toolkit 2003).
I've heard it is possible to copy the Toolkit bin folder to the VS 2003 bin folder, but I don't know if it'll work with VS6.
But I think it is worth trying... (after having made a backup copy of your VS6 bin folder, just in case everything goes broken...).
Before doing that you may want to check if the new cl.exe and link.exe accept the same flags as the old VS6 ones.


OK i have solved this problem.But it's like "oh my God" for me and my clean code. I will consider it as a bug in visual studio.
it looks like template methods definition have to be? inside class declaration.


"oh my God" I didn't see that either!
But I don't think it's a VS bug. If I recall correctly I ran into similar problems with BCB.

What if you try this :

class Something
{
? template<class T>
? void member(T var);
};

template<class T>
void Something::member<T>(T var)
{
...
};


(note the <T> specialization between the Something::member identifier & it's arguments, and the function body must still be in the header).? :?:

It may be wrong as this is from memory only. I'm really too tired to try it right now, my screen is dancing before my eyes... ;)
C'ya? :)
Posted on 2005-06-11 18:10:23 by chep
You are wrong  :P. But thanks for the reply anyway.

I have found another "discomfort" in VS  when i make changes in my template which is inside header and this header is included in precompiled header stdAfx than the changes are not made until i change something in source file where i call this method and then compile it.
Posted on 2005-06-11 18:26:44 by AceEmbler
That's right, template methods are only generated when they're used, same with vs.net 2003 afaik. Regarding your earlier woe, I think you should have put


ErrorH->PrintTable<int>("huh",(int*)&i,1,0);


or?
Posted on 2005-06-11 18:42:12 by stormix

BTW i thought that VS is the best IDE for win32 C++ out there

Whether it's the best IDE is a pretty personal thing, but it's one of the best and most standards-conformant C++ compilers. Or, rather, vc2003 is. vc6 is pretty crappy by today's standards, especially wrt. templates... but remember, it's an old compiler by now.


it looks like template methods definition have to be  inside class declaration.

It doesn't have to be inside the class declaration, but it has to be in the header file. You can define just the prototype in the class, then the class::function body later in the header file, outside the class. *very* recent compilers have a way to put templates in .cpp files, but iirc it's only comeau that supports this, and there's talk about dropping this from The Standard since it's too complicated. So, always put templates in a header file.


I've heard it is possible to copy the Toolkit bin folder to the VS 2003 bin folder, but I don't know if it'll work with VS6.

It will work, although you'll have to specify some options manually, and you probably won't be able to use the debugger... there was a thread about it somewhere.


I have found another "discomfort" in VS  when i make changes in my template which is inside header and this header is included in precompiled header stdAfx than the changes are not made until i change something in source file where i call this method and then compile it.

You shouldn't use stdafx.h simply as a way to include all your header files. It's only meant to be used with static header files, like the PlatformSDK and libc. Otherwise you're going to run into trouble. Specifically, never include headers with templates in precompiled headers.
Posted on 2005-06-12 06:23:33 by f0dder



ErrorH->PrintTable<int>("huh",(int*)&i,1,0);



I don't have to do it like this because compiler recognize type of pointer and create proper function.
Posted on 2005-06-12 06:26:20 by AceEmbler


it looks like template methods definition have to be  inside class declaration.

It doesn't have to be inside the class declaration, but it has to be in the header file.


You're right, but VC6 has a bug: the member function template's body needs to be inside the class definition for it to work. I advise upgrading to a newer compiler, VC6 is broken in many many evil ways.


there's talk about dropping this from The Standard since it's too complicated.


Yes, there's a proposal from Herb Sutter to remove the "export" keyword from the language. I don't think it will get removed, though.


Specifically, never include headers with templates in precompiled headers.


Why? I do it all the time.
Posted on 2005-06-12 12:30:14 by death