|
Wouldn't a "normal" function object work just as well? E.g.:
struct IsID
{
LPCTSTR id_;
IsID(LPCTSTR id) : id_(id) { }
bool operator()(const CMyClass* p) const
{
return pClass->GetID() == id_;
}
};
}
...
if (find_if(myarray.begin(), myarray.end(), IsID(string)) == myarray.end())
{
}
I am still relatively new to STL, so am keen to learn what advantages deriving from unary_function will give you. Do you have more details and examples?
|
|
|
|
|
Yeah this would work just fine but it's not "adaptable". STL functions such as bind1st and bind2st reply on certain typedef s (metadata if you like) being present to work. The simplest way to supply them is to derive from unary_function or binary_function .
Steve
|
|
|
|
|
True. I would just add that boost::bind does not require the typedefs, so if you are using boost, this is not an issue.
My programming blahblahblah blog. If you ever find anything useful here, please let me know to remove it.
|
|
|
|
|
Yeah, Boost's Bind and Lambda libraries add considerably to what can be done with STL alone.
Steve
|
|
|
|
|
Oh that's what I was missing! I have seen a lot of functors examples but they rarely had their own constructor. Thanks!
|
|
|
|
|
The find_if can work if you use a good smart pointer that uses value semantics for the comparison.
Check out the following link:
http://axter.com/smartptr
The above smart pointer uses value semantics, so that the pointee is compated instead of the pointer address.
Top ten member of C++ Expert Exchange.
http://www.experts-exchange.com/Cplusplus
|
|
|
|
|
hi all
i had make drawing. now i want that these drawing should be saved in bmp file or the jpeg file tell me how to do that or any other place such as picturebox where i can draw ans save as bmp file.
ddd
|
|
|
|
|
I found when I have subclassed a child control( like tree view control), the child cannot be sure it can receive all the WM_CONTEXTMENU message, sometimes the WM_CONTEXTMENU gone. but the parent dialog can always receive the WM_CONTEXTMENU. the message like notify message can be sent to child all the time.
Now I handle the WM_CONTEXTMENU in the parent, and then pass it to the child, this way is a little sucks.
Someone can help me to pass the WM_CONTEXTMENU to child?;P;P;)
Single Simple
Double Trouble
|
|
|
|
|
|
|
Hi
I want to pass a member function to the std::for_each algorithm but strguggling. I've seen where you can use std::mem_fun to bind a member function of the 'contained' class, but I want a member function of a different class...code below shows what I want to do and code after that shows my work around.
I could use a for..next loop, but don't think I should when these algorithms are so d*** neat!
What I want to do....
class myClass
{
private:
void DoSomethingWithString( std::string *pString );
public:
void Go()
{
std::set <std::string > myStrings;
myStrings.insert("ABC");
myStrings.insert("DEF");
myStrings.insert("GHI");
std::for_each(myStrings.begin() , myStrings.end() , );
}
};
and a work around....
class myClass
{
class DoStringThing
{
private:
myClass* m_class;
public:
DoStringThing( myClass* class_param) : m_class( class_param)
{
}
void operator()( std::string &filename)
{
m_class->DoSomethingWithString( &filename );
}
};
friend class DoStringThing;
private:
void DoSomethingWithString( std::string *pString );
public:
void Go()
{
std::set <std::string> myStrings;
myStrings.insert("ABC");
myStrings.insert("DEF");
myStrings.insert("GHI");
std::for_each(myStrings.begin() , myStrings.end() , DoStringThing(this) );
}
};
So, how can I call a member of the class that is executing the for_each...?
Regards
Angel
*********************************************
The sooner you fall behind, the longer you have to catch up.
|
|
|
|
|
Correct. Function object is a good solution in this example.
Kuphryn
|
|
|
|
|
Hi - thanks for the answer. I really want to know how to call a member function instead of using a functor.
Is it possible?
Cheers
Regards
Angel
*********************************************
The sooner you fall behind, the longer you have to catch up.
|
|
|
|
|
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));
|
|
|
|