|
There are more elegant solutions with function objects.
Kuphryn
|
|
|
|
|
Yes, I know, but I would still like to now how to use a member function....
Regards
Angel
*********************************************
The sooner you fall behind, the longer you have to catch up.
|
|
|
|
|
Definitely! Update when you figure out the solution without overloaded operator().
Kuphryn
|
|
|
|
|
Also, there is bind2nd().
Kuphryn
|
|
|
|
|
Hello Angel1058,
One way you can achieve the use of a member function is to declare a class deriving from std::string :
class MyString : public std::string
{
public :
MyString()
{
}
MyString(const char* pstring) :
std::string(pstring)
{
}
~MyString()
{
}
void DoSomethingWithString()
{
std::cout << c_str() << std::endl;
}
};
Yes, you basically extend the std::string with a public member function named DoSomethingWithString().
Then in myClass::Go(), you use MyString instead of std::string :
void Go()
{
std::set<MyString> myStrings;
myStrings.insert("ABC");
myStrings.insert("DEF");
myStrings.insert("GHI");
std::for_each
(
myStrings.begin(),
myStrings.end(),
mem_fun_ref(&MyString::DoSomethingWithString)
);
}
Yes, you would have seen it by now, use mem_fun_ref() as the predicate for for_each(). Basically, MyString::DoSomethingWithString() wsill be called on each contained object in myStrings (which is a set of MyString objects).
Give it a try.
Best Regards,
Bio.
|
|
|
|
|
Not meaning to sound ungrateful, I am grateful, always for the time CPians give, but I don't want to call a member of the contained object. I don't want to use a functor. I don't want to use a static member function. I want to use a member of the class that invokes the for_each.
class MyClass
{
public:
void DoSomethingWithString( std::String *ptrToString()
{std::cout << ptrToString;}
void LookThroughContainer( std::vector &c)
{
for_each(c.begin() , c.end() , );
}
};
Just call the MyClass::DoSomethingWithString member for each element in a container from MyClass::LookThroughContainer. I *KNOW* this isn't the best way to do this, functors are, but I want to know a) IF you can do it and b) HOW you can do it.
Thanks again for all your time
Regards
Angel
*********************************************
The sooner you fall behind, the longer you have to catch up.
|
|
|
|
|
Try this:
std::bind1st(std::mem_fun1(&myClass::DoSomethingWithString), this)
mem_fun1 is no longer part of the C++ standard (it's old school) but if you're using an old compiler/STL (like MSVC6) you'll have to use it to get it to work. Most new environments provide it for backwards compatibility.
I think you'll have to remove the private on the DoSomethingWithString function. I can think of a workaround for this is it offends you but I'm not sure it's worth the effort.
Steve
|
|
|
|
|
Finally !!! Many thanks. I thought I had tried most combinations of bind1st / Bind2nd with mem_fun / mem_fun1, but clearly not. I appreciate your time.
Regards
Angel
*********************************************
The sooner you fall behind, the longer you have to catch up.
|
|
|
|
|
Steve,
I am trying to do something very similar, but I cannot get your sample to compile. I have boost, so there may be a better way to do this, but basically I am trying to do the same thing - i.e. use some variant of bind to call a member function of the class that is calling for_each, e.g.:
class CTest
{
public:
void SomeFunc(const std::wstring& str) const
{
}
void DoSomething(void) const
{
std::vector<std::wstring> v;
v.push_back(L"test");
...
for_each(v.begin(), v.end(), std::bind1st(std::mem_fun1(&CTest::SomeFunc), this));
}
Any hints before my head explodes?
|
|
|
|
|
There's nothing wrong with your code, which makes me think you're using MVSC6 - It's your compiler. On a real compiler your code will work. To make it work form MSVC6 change SomeFunc so it returns something. i.e.
bool SomeFunc(const std::wstring& str) const
{
return true;
}
The flaw in MSVC6 is illustrated below:
void ReturnsVoid() {}
void CallsReturnsVoid()
{
return ReturnsVoid();
}
This code should compile - A void function can't return with return void; but it should be able to return with return ReturnsVoid(); .
This feature is very important when writing generic functions with templates.
Steve
|
|
|
|
|
Steve,
I am actually using Visual Studio 2005 - so have MSC8 (with an STL that I thought was meant to be pretty good!).
Either way - with or without returning something - the code still won't compile.
Here it is in full:
#include "stdafx.h"
#include <windows.h>
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
class CTest
{
public:
void SomeFunc(const std::wstring& str) const
{
OutputDebugString(str.c_str());
}
void DoSomething(void) const
{
std::vector<std::wstring> v;
v.push_back(L"test");
for_each(v.begin(), v.end(), std::bind1st(std::mem_fun1(&CTest::SomeFunc), this));
}
};
int _tmain(int argc, _TCHAR* argv[])
{
CTest test;
test.DoSomething();
return 0;
}
When I compile this, I get the following error:
error C2782: 'std::mem_fun1_t<_Result,_Ty,_Arg> std::mem_fun1(_Result (__thiscall _Ty::* )(_Arg))' : template parameter '_Ty' is ambiguous
c:\program files\microsoft visual studio 8\vc\include\functional(604) : see declaration of 'std::mem_fun1'
could be 'const CTest'
or 'CTest'
If I remove 'const' from the two methods, I get lots of different errors. Head meet brick wall.
|
|
|
|
|
Steve,
Thanks to the boost list and Stuart Dootson, I have a solution using boost::bind :
for_each(v.begin(), v.end(), bind(&CTest::SomeFunc, this, _1));
|
|
|
|
|
|
I want to pass my own information to propertypage that is created by propertysheet using "AddPage"&"Create".
But I found the fild "lParam" in m_psp has been used by WTL for core wrapp
Is there any method I can pass my own info to propertypage when they are created, initialize before shown.
-- modified at 9:20 Friday 10th March, 2006
|
|
|
|
|
|
Hello,
I was wondering if it is possible to implement MDI in a MFC based ActiveX control. I was able to implement SDI (using a sample from MSDN), but I faced some difficulties when implementing MDI. Any help would be highly appreciated.
Thanks in advance,
Dennis.
|
|
|
|
|
|
Disable "Minimize CRT use in ATL" in your project properties, and it should work.
|
|
|
|
|
Thanks a lot! That's really fantastic.
|
|
|
|
|
Does any one know how to make modeless dlgs/propertysheets destroy by themself?
my code:
<br />
pdlg = new CMyDlg;<br />
if(pdlg && pdlg->Create(hwndParent))<br />
pdlg->ShowWindow(SW_SHOW);<br />
<br />
void OnClose(UINT uCode, int nID, HWND hwndCtrl)
{<br />
DestroyWindow();<br />
}<br />
void OnNcDestory(void)<br />
{<br />
m_hWnd = NULL;<br />
delete this;
}<br />
But it works fine in MFC
http://www.codeproject.com/dialog/gettingmodeless.asp[^]
any idea?
-- modified at 10:34 Thursday 9th March, 2006
|
|
|
|
|
Override OnFinalMessage.
void OnFinalMessage(HWND /*hWnd*/)
{
delete this;
}
|
|
|
|
|
hfry wrote: Override OnFinalMessage.
void OnFinalMessage(HWND /*hWnd*/)
{
delete this;
}
Crashed!
I found that the m_hWnd is NULL when running to "delete this;".
But m_hWnd is reset again after the destructor of base class "CWindowImplRoot" is invoked-- line 2752 in file atlwin.h
BTW: I'm using WTL8.0.
-- modified at 7:55 Friday 10th March, 2006
|
|
|
|
|
Are you using VC6? or VC7+? If VC6 maybe you should look at Michael Dunn's post.
If it's happening in VC7.1, there was this long discussion on the WTL Yahoo forums a while back. I'm not sure if VC8 suffers from this problem.
http://groups.yahoo.com/group/wtl/message/10095[^]
|
|
|
|
|
The windowing code is from atlwin.h which is from ATL. So this is not part of WTL. WTL is built on top of ATL's windowing code so having the most updated WTL doesn't help.
New versions of ATL only ship with new versions of Visual Studio. The ATL files that is in the Platform SDK seems rather old.
|
|
|
|
|
There is a CBitmapButton IDC_CLOSE in my Dialog.
I destroy the whole Dialog in OnClose callback function
<br />
void CDlg::OnClose(UINT uCode, int nID, HWND hwndCtrl)<br />
{<br />
DestroyWindow();<br />
}<br />
When the Main Dlg is deleted, it crashed at line 2752 in file atlwin.h
<br />
if(m_hWnd != NULL)
{<br />
ATLTRACE(atlTraceWindowing, 0, _T("ERROR - Object deleted before window was destroyed\n"));<br />
ATLASSERT(FALSE);<br />
}<br />
The m_hWnd is the handle of button IDC_CLOSE!
|
|
|
|