|
I'm trying to implement a "MFC CList look-alike" wrapper on top of the STL list using MS Visual C++ 2005 Express.
The implementation of the iteration methods begin-next-prev-end requires a storage of the position in the class like this:
<br />
#include <list><br />
template< class TYPE> <br />
class CList<br />
{<br />
protected:<br />
std::list< TYPE >::iterator pos;<br />
...<br />
But it doesn't work... I get these compiler errors:
warning C4346: 'std::list< TYPE >::iterator' : dependent name is not a type
error C2146: syntax error : missing ';' before identifier 'pos'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
I don't quite understand the errors. Using the same declaration (std::list< TYPE >::iterator p) in a member function, I don't get any errors at all from the compiler.
Why am I not allowed to declare this iterator (pos) as a member in the class? Hope someone can help?
-- modified at 11:45 Tuesday 5th June, 2007
-- modified at 11:46 Tuesday 5th June, 2007
Anton112
|
|
|
|
|
Interesting, as your code snippet compiles fine with VS6.
template<class T>
class CList
{
protected:
std::list<T>::iterator pos;
}; I'd guess that it has to do with VS2005 being more C++ compliant. See here.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Well, I have to admit that I don't know anything about compilers in that sense. Hence, I don't know anything about differences between specific compilers. In fact, years agy I tried to be a Windows developer, but it is years ago...
Anton112
|
|
|
|
|
iterator cannot be deduced as a type by the compiler. To make it (compiler) think so, put typename in front of its declaration;
template<class T>
class CList{
protected:
typename std::list<T>::iterator pos;
};
--
=====
Arman
|
|
|
|
|
Thanks, Arman
You gave me my answer...
Anton112
|
|
|
|
|
Hello I do not know if this messageboard is the good one !
I have a problem with fonction recev
the code under MFC VS2005
Before I get a connection with accept(...)
rVal = recv(m_acceptSocket,messageStream,BUFFER_SIZE,0);
if ( rVal == 0 || rVal == WSAECONNRESET || rVal==SOCKET_ERROR) {
m_clientConnected=false;
if (rVal==SOCKET_ERROR)
{
int errorCode = 0;
string errorMsg ="error calling recv():\n";
//void detectErrorRecv(int* errCode,string& errMsg)
//{
//*errCode = WSAGetLastError();
//if ( *errCode == WSANOTINITIALISED )
//else if ...
}
detectErrorRecv(&errorCode,errorMsg);
}
}...
My problem is that the error do not match with any error possible for the fonction recev (WSANOTINITIALISED ,WSAEADDRINUSE ,......)
I do not undestand how it his possible.
Thank you for help me !
AutreChien
|
|
|
|
|
NorGUI wrote: My problem is that the error do not match with any error possible for the fonction recev (WSANOTINITIALISED ,WSAEADDRINUSE ,......)
Do you know ALL of the error codes that recv() could return? There are 2000 socket-related codes. What is the value or rVal ?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
recv() doesn't return an error code.
rVal = recv(m_acceptSocket,messageStream,BUFFER_SIZE,0);
if (rVal == SOCKET_ERROR)
{
int nWSAErr = WSAGetLastError();
if (nWSAErr == WSAECONNRESET)
{
}
else if (nWSAErr == ...)
{
}
}
else if (rVal == 0)
{
... the connection has been closed
}
else
{
... bytes were received
}
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Hi. I´m trying to run my app after creating the setup and installing it on a clean computer, I mean, with the OS recently installed to avoid finding "extra" dll around.
After installing the app with no errors, when I run I see nothing. No error, no program, nothing. In the task manager I hace checked that it starts and finishes in about a second. In my computer, it works fine, but I want to check how would it work on the costumer´s computer.
I have used a program (Dll Show by Design) to know whick dll and other files does the program use, and here is the list:
advapi32.dll
clbcatq.dll
comctl32.dll
comctl32.ocx
comdlg32.dll
conres.dll
dnsapi.dll
fm20.dll
fm20esn.dll
gdi32.dll
hnetcfg.dll
kernel32.dll
mfc42.dll
mfc42loc.dll
mscomm32.ocx
msctf.dll
msflxgrd.ocx
msvcrt.dll
mswsock.dll
netapi32.dll
ntdll.dll
ntwdblib.dll
ole32.dll
aleaut32.dll
olepro32.dll
riched20.dll
rpcrt4.dll
secur32.dll
shell32.dll
shlwapi.dll
sxs.dll
tmb.exe
user32.dll
uxtheme.dll
version.dll
winrnr.dll
wldap32.dll
ws2_32.dll
ws2help.dll
wshtcpip.dll
My question is:
I know that the exe must be included on the setup.exe (of course), and if I include all this files it could be risky that there are some files like kernel32.dll that are unique in each computer so, do you see any file in the list that you think could be necessary in the setup? Should I include the ocx like msflxgrd.ocx os mscomm.ocx?
Thanks!
Time to come clean...
Vive y deja vivir / Live and let live
Javier
|
|
|
|
|
garfield185 wrote: In the task manager I hace checked that it starts and finishes in about a second.
Sounds like an ActiveX control has not been registered.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
I have checked that, and all the controls are registered. I use a .bat file to use RegSvr32 and register the ocx, and all the dll that I put on system32 folder. Any other idea?
I have tried many times and different ways, but I just can´t...
Time to come clean...
Vive y deja vivir / Live and let live
Javier
|
|
|
|
|
How do u pass a Cstring into a function that accepts LPSTR?
|
|
|
|
|
tom groezer wrote: How do u pass a Cstring into a function that accepts LPSTR?
If you have _UNICODE defined then you have to use W2A macro
#include <atlconv.h>
USES_CONVERSION;
CString csSomeString = _T( "Nibu" );
LPSTR lpsz = W2A( csSomeString );
else if _UNICODE not defined then
CString csSomeStr = _T( "Nibu" );
LPSTR lpsz = csSomeStr.GetBuffer( 0 );
csSomeStr.ReleaseBuffer();
|
|
|
|
|
|
CString cstring;
LPSTR str = cstring.GetBuffer();
//access str
cstring.ReleaseBuffer();
With some Windows API, which take a LPSTR but do not write to it and would only need a LPCTSTR, I am sloppy and use the (LPSTR)(LPCTSTR) casting hack.
Disclaimer:
Don't try this at home kids, we are trained professionals.
Neither me or my company endorse this coding style implicitly or explicitly.
Failure is not an option - it's built right in.
|
|
|
|
|
Thr trite answer is, that depends on what the function wants to do with the LPSTR.
You can call mycstring.GetBuffer(0); to get a pointer to the internal text buffer in the CString object. If you're working in ASCII and not UNICODE then that pointer should match up with LPSTR. If the function you're calling expects the string to be of at least a minimum length then use mycstring.GetBuffer(nMinLength); to get a buffer of at least nMinLength characters. If doing this actually makes your CString longer you can call <code>mycstring.ReleaseBuffer(); afterwards to let the buffer shrink to only what's needed.
If the function that takes a LPSTR wants to write into the string you have to be very careful to pass a big enough buffer and validate it afterwards. mycstring.GetBufferSetLength(nLength); can sometimes be useful for this sort of thing. CStrings are useful but slippery customers
Nothing is exactly what it seems but everything with seems can be unpicked.
|
|
|
|
|
tom groezer wrote: How do u pass a Cstring into a function that accepts LPSTR?
Usually the above is NOT a good idea, unless yoou know that the function doesn't change the passed buffer. Typically there are the following scenarios:
(1) The function doesn't change the buffer.
(2) The function changes the buffer and it accepts the size of the buffer as parameter
The better way to handle point (1) is rewriting the function prototype in order to accept a LPCSTR argument instead of a LPSTR one, then passing to the function directly the CString object (CString implements a LPCSTR cast operator). If you cannot change the function prototype, but ARE SURE that function doesn't change the buffer, then use the CString::GetBuffer method).
To handle scenario (2), use CString::GetBuffer in a consistent way, for instance:
void fillBuffer(LPSTR lpszBuffer, INT nBufferSize);
void myFunction()
{
const int nSize = 10;
CString myString;
fillBuffer( myString.GetBuffer(nSize), nSize);
myString.ReleaseBuffer();
}
If you hve any doubts, see GetBuffer documentation here [^].
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
Please look at CString::operator LPCTSTR
CString strTemp;
(LPCTSTR)strTemp;
Regards,
Paresh.
|
|
|
|
|
Paresh Chitte wrote: Please look at CString::operator LPCTSTR
Did you miss the "that accepts LPSTR" part?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
As I didn't know thist GetBuffer ()... I made my own text transformation. I write it down:
char m_cName [20];
LPTSTR CMyClass::TransformTextFormat (const CString szString)
{ for (int i = 0; i < 20; i++)
m_cName[i] = NULL;
for (int j = 0; j < szString.GetLength (); j++)
m_cName[j] = szString[j];
return &m_cName[0];
}
I know is not the most "pretty" way... but it works
Greetings.
--------
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
|
|
|
|
|
Your code will experience troubles with strings longer than 20 characters.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
Thanks for the advice...
I supposed so, but there is no problem. I use it in my application with visual/interactive elements whose names are limited to 16 chars.
Anyway... If the char m_cName is set to 100, would it then works with longer names? or still have problems with the length?
Greetings.
--------
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
|
|
|
|
|
Nelek wrote: If the char m_cName is set to 100, would it then works with longer names? or still have problems with the length?
As soon as the length of the string you are assigning (including the end-NULL-byte) is greater than your buffer you have produced a so called buffer overrun error.
That may or may not go unnoticed for a while, but is a sure recipe for disaster.
Failure is not an option - it's built right in.
|
|
|
|
|
Nelek wrote: Anyway... If the char m_cName is set to 100, would it then works with longer names? or still have problems with the length?
No. AFAIK CString can hold several thousand (virtually, an infinite number of) characters, hence your code will not handle properly big CStrings.
On the overall, your code:
Nelek wrote:
m_cName [20];
LPTSTR CMyClass::TransformTextFormat (const CString szString)
{
for (int i = 0; i < 20; i++)
m_cName[i] = NULL;
for (int j = 0; j < szString.GetLength (); j++)
m_cName[j] = szString[j];
return &m_cName[0];
}
has, IMHO several flaws:
(1) you should not define variables in header files (only declarations there). If you include the same header file in some source files (that is the usual scenario) then you experience compiler errors.
(2) The function, as it stands, relies on the factthat its argument has a lenght less than a certain amount (unless you use Design by contract technique...). This is dangerous: you have to handle bigger input buffers, without going out of the array boundaries (e.g. copying maximum 19 characters - you need the trailing NULL).
(3) code is inefficient, you first initialize to NULL a characther at time, then copy, a character at time, the CString into your buffer. The first operation is not required, the second one may be performed copying the whole buffer at once (of course you need to NULL terminate the string).
BTW efficience may be not a ISSUE, but reliability must be.
Hope that helps.
(3)
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
Yes, it is a good explanation. I will take it in consideration. Thanks for the tips and corrections.
Greetings.
--------
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
|
|
|
|