|
No, it's not in 1.33.1. It's only one file however and can be downloaded from here[^]. As you can see it will be "shipped" with 1.34. I use 1.33 but added this file manually.
Steve
|
|
|
|
|
Thanks Steve.
Having problems using BOOST_FOREACH with a std::map though. For example, this won't compile:
std::map<int, int> m;
BOOST_FOREACH(std::pair<int, int> p, m)
{
}
This does work however:
std::map<int, int> m;
std::pair<int, int> p;
BOOST_FOREACH(p, m)
{
}
Is there a way to avoid declaring the pair before the FOREACH loop?
|
|
|
|
|
This is because BOOST_FOREACH is a macro. See here[^]. There are many ways to fix this including a typedef or an extra pair of brackets, but in this case the best is the following:
typedef std::map<int, int> collection_t;
collection_t m;
BOOST_FOREACH(collection_t::value_type p, m)
{
}
In general, with of without using BOOST_FOREACH , it's best to use a typedef to define an alias to the collection type, here collection_t . This allows us to change the type of collection used in one place. Once this is done we use the value_type typedef which is in every STL collection.
I'd probably use a reference, const if possible, like this:
typedef std::map<int, int> collection_t;
collection_t m;
BOOST_FOREACH(const collection_t::value_type &p, m)
{
}
In both these examples the actual type name of the collection is only mentioned in one place and so can be easily changed. When for hash maps are added to STL, for example, this would mean that you can switch between a hash map or binary tree by changing only one line.
Steve
|
|
|
|
|
Steve, thanks again for another informative post! The value_type typedef is something I shall be using a lot more of in future.
|
|
|
|
|
Hello Experts,
I am involved into developement of Toolbar for IE.
In that I have one drop down menu- button.
I want the menu items of this menu to be hyperlinks.
A single menu item can have more than on words each poiting to
different websites.
These menutems are owner-drawn.
Please tell me how I put hyperlinks on MenuItems.
I am using WTL.
Still,if anyone knows how to do it in MFC,let me know.
I will port it to WTL myself!!!!!!!!
Thanks in advance
|
|
|
|
|
Hyperlinks in menus? Huh? I thought a menuitem was a hyperlink of sorts...
--
Mit viel Oktan und frei von Blei, eine Kraftstoff wie Benziiiiiiin!
|
|
|
|
|
Did you see hyperlink on menus in a application?
|
|
|
|
|
hi all i m using the fopen fclose in ATL and it work fine with debug version when i change the project configuration to the Releasewithmindependancy then following errrs occurs.
d:\_TasleemWork\_bho\BhoNew_src\BhoNew\BhoApp.cpp(71): error C3861: 'fclose': identifier not found, even with argument-dependent lookup
d:\_TasleemWork\_bho\BhoNew_src\BhoNew\BhoApp.cpp(80): error C3861: 'fclose': identifier not found, even with argument-dependent lookup
d:\_TasleemWork\_bho\BhoNew_src\BhoNew\BhoApp.cpp(76): error C3861: 'fopen': identifier not found, even with argument-dependent lookup
d:\_TasleemWork\_bho\BhoNew_src\BhoNew\BhoApp.cpp(67): error C3861: 'fopen': identifier not found, even with argument-dependent lookup
d:\_TasleemWork\_bho\BhoNew_src\BhoNew\BhoApp.cpp(69): error C3861: 'fwrite': identifier not found, even with argument-dependent lookup
i dont know why these are bcos i m new in ATL
Tasleem Arif
|
|
|
|
|
tasleem143 wrote: Releasewithmindependancy
This is your problem - fopen, etc. are part of the C runtime library and a "min dependency" release won't include it. You need to change the project settings and change "Minimize CRT use in ATL" to "No".
|
|
|
|
|
That should only cause a problem at link time...? Judging by this fellow's error messages, he is having compile time errors.
--
Mit viel Oktan und frei von Blei, eine Kraftstoff wie Benziiiiiiin!
|
|
|
|
|
Or worse, at runtime.
Steve
|
|
|
|
|
Been there. Done that. Felt incredibly stupid.
I remember an app I wrote with ATL3. It was complaining about main not being defined. "What the hell??" I thought, it was a windows app! So I just snuck in an empty main(), and it ran quite well. Until some bizarre errors started to occur deep down inside the STL. I later learned that I had to remove the minimize CRT setting. I felt really stupid that day.
--
Torn from tomorrow's headlines
|
|
|
|
|
these errors at Compile time errors.
Tasleem Arif
|
|
|
|
|
Maybe you need to #include <stdio.h> ?
|
|
|
|
|
it did not work 2
Tasleem Arif
|
|
|
|
|
There are a number of standart Windows controls, such as Tab Control, that can own another - for example we may place other controls on tabs of Tab Control in the design time, then use them in run time. How can one achieve the same functionality in owner-written (ATL) ActiveX Full Control? I mean how to make my component avaliable to place other components in it in design-time. May be there are some links, or statements about such tasks?
|
|
|
|
|
Hi all, I'm confused and liked to know your opinion.
In short:
I think there is a general WTL::CString design problem if a CString is
passed by reference between DLLs to retrieve data.
Example, calling the following DLL-provided method to this is not safe:
int GetName(CString& o_strName);
In long:
Referring to ATLMISC.H, an empty CString will point to a global
variable named rgInitData. rgInitData acts as a global placeholder to be pointed to for any initially empty strings.
<br />
_declspec(selectany) int rgInitData[] = { -1, 0, 0, 0 };<br />
<br />
_declspec(selectany) CStringData* _atltmpDataNil = (CStringData*) &rgInitData;<br />
Since any file that uses WTL::CString #inlcudes the code above, it will get an rgInitData in for each obj file, to avoid linker problems the declspec is used. Thats ok so far.
But problems arise in case of DLL projects, as each DLL will get its own rgInitData instance with the corresping atltmpDataNil pointer.
The problem is: create an empty CString in DLL-A, the CString will point to its rgInitData-A object to indicate it is empty.
Now handing this CString object over to DLL-B, then the CString internal implementation uses the address of rgInitData-B to determine if its an empty string or not.
As the match will fail, the DLL-B side implementation assumes there is data to be freed, resulting in attempting to free rgInitData-A (which is a global variable on the stack).
Do you agree? Do you know a workaround?
Regards
Xavi
Please note, that here no Debug/Realease or MFC, non-MFC issues apply.
|
|
|
|
|
You're seeing the general problem of trying to pass objects between modules that are using the CRT allocator. This may work, if you're using the DLL version of the CRT, but is bad practice since it may not work in future versions of the CRT. You need to use a process-wide allocator such as CoTaskMemAlloc() /CoTaskMemFree() when passing data between modules.
|
|
|
|
|
Hi Mike
Thanks a lot for your input, I'm glad for any opinion, though (hopefully not beeing a nitpicker) this here is actually a different problem (or isn't it?)
I totally agree that the "pass object between DLLs" is serious topic on itselfs and has to be managed carefully when it comes to allocation/deallocation.
Actually I think we manage it correctly here (linking all to the CRT-DLLs).
Let me put it this way: I'm quite sure we use the same allocs/deallocs, but because the CString internal logic uses a pointer to something that exists per DLL, passing a CString between the DLLs will cause the logic to fail and to deallocate where a deallocation is not appropriate.
To make things worser, this only applies for empty strings, as soon as the string points to heap allocated memory, the logic works fine.
So I came to the conclusion, seeing a CString& in a DLL interface is a problem.
It seems MFC has the same problem, using MFC-extension DLLs to manage it (http://www.sources.ru/cpp/mfc/t4650.htm[^])
Xaver Birrer
Visual C++ MCSD
|
|
|
|
|
Ah yes, good point about the special "empty" string object. Fortunately (although it's not very convenient) you can work around it by assigning "" to CString s, which doesn't break other code like IsEmpty() .
|
|
|
|
|
Yo coders,
I am experimenting with the following code, using VC++ 6:
.............
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <string>
#include <list>#include <functional>
using namespace std;
class test
{
public:
int m_i;
test(int i = 0)
{
m_i = i;
cout << "test object with m_i=" << m_i << " being constructed" << endl;
};
~test()
{
cout << "test object with m_i=" << m_i << " being deleted" << endl;
};
};
typedef list<test> TESTLIST;
int main(int argc, char* argv[])
{
TESTLIST myTestList;
myTestList.push_front(1);
myTestList.push_front(2);
return 0;
}
.........
The output of the program is:
test object with m_i=1 being constructed
test object with m_i=1 being deleted
test object with m_i=2 being constructed
test object with m_i=2 being deleted
test object with m_i=2 being deleted
test object with m_i=1 being deleted
........
How is it possible that objects can be constructed once but deleted twice?
thanks,
Neil
cheers,
Neil
|
|
|
|
|
If you add monitoring of the copy constructor, you'll find the missing constructions...
#include <iostream>
#include <list>
using namespace std;
class test
{
public:
int m_i;
test(int i = 0)
{
m_i = i;
cout << "test object with m_i=" << m_i << " being constructed" << endl;
};
test(test const& t) : m_i(t.m_i)
{
cout << "test object with m_i=" << m_i << " being copy constructed" << endl;
};
test& operator=(test const& t)
{
m_i = t.m_i;return *this;
cout << "test object with m_i=" << m_i << " being copy constructed" << endl;
};
~test()
{
cout << "test object with m_i=" << m_i << " being deleted" << endl;
};
};
typedef list<test> TESTLIST;
int main(int argc, char* argv[])
{
TESTLIST myTestList;
myTestList.push_front(1);
myTestList.push_front(2);
return 0;
}
gives
test object with m_i=1 being constructed
test object with m_i=1 being copy constructed
test object with m_i=1 being deleted
test object with m_i=2 being constructed
test object with m_i=2 being copy constructed
test object with m_i=2 being deleted
test object with m_i=2 being deleted
test object with m_i=1 being deleted
|
|
|
|
|
When writing classes that you want to place into STL containers, make sure you declare a copy constructor and copy-assignment operator. The containers to a lot of copying, and make use of those two functions. Since you didn't declare one, the compiler generates a default one for you (which basically does a memcpy).
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
Thanks, I realised my mistake soon after... this is only my 2nd day working with STL!
So it is best to only put simple types, strings or pointers in a list then, and not "large" objects directly .. as there doesn't seem to be a member function to remove an object from a list without deleting it!
cheers,
Neil
|
|
|
|
|
You can place large objects in a list if you like, just realize that it will be expensive to do things like sort it (especially if the list has a substantial number of elements).
list::erase will remove an element from the list. If the element was controlled by the list (that is, you created a list like list<MyObjects> myList; ), then yes, it will be deleted. If you want a copy of it, you should grab it prior to calling erase. If the list was a list of pointers, erase will just delete the pointer. The object the pointer was pointing to will still be there (so make sure you have a pointer that still points to it somewhere or you will have a memory leak).
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|