 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Mockey Chen Guest
|
Posted: Wed Jun 21, 2006 2:56 pm Post subject: Using operator() as return a reference to class self |
|
|
Overload operator() is magic in C++, since you can implement
a functor using operator(), the behave like a normal function.
I found we can use a trick that operator() return a reference to
class self. According return value, we can do a recursive call
operator(), this idiom can be used to initialize a list like class,
such as list, deque, vector...
There is an example:
#include <list>
#include <iostream>
#include <iterator>
#include <algorithm>
template<typename T>
class cmlist : public std::list<T>
{
public:
// Note: here *MUST* return a reference to class self
cmlist& operator()(const T& e)
{
this->push_back(e);
return *this;
}
};
int main()
{
cmlist<int> il;
// Note: using recursive call operator to
// initialize the list.
// avoid using 3 line to call 3 push_back()
il(3)(4)(5);
std::copy(il.begin(),
il.end(),
std::ostream_iterator<int>(std::cout, " "));
return 0;
}
Any suggestion?
--
Regards.
Mockey Chen
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Carl Barron Guest
|
Posted: Thu Jun 22, 2006 4:01 pm Post subject: Re: Using operator() as return a reference to class self |
|
|
In article <e792fd$7s0$1 (AT) news (DOT) yaako.com>, Mockey Chen
<mockey.chen (AT) google (DOT) com> wrote:
| Quote: | Overload operator() is magic in C++, since you can implement
a functor using operator(), the behave like a normal function.
I found we can use a trick that operator() return a reference to
class self. According return value, we can do a recursive call
operator(), this idiom can be used to initialize a list like class,
such as list, deque, vector...
There is an example:
#include <list
#include <iostream
#include <iterator
#include <algorithm
template<typename T
class cmlist : public std::list<T
{
public:
// Note: here *MUST* return a reference to class self
cmlist& operator()(const T& e)
{
this->push_back(e);
return *this;
}
};
int main()
{
cmlist<int> il;
// Note: using recursive call operator to
// initialize the list.
// avoid using 3 line to call 3 push_back()
il(3)(4)(5);
std::copy(il.begin(),
il.end(),
std::ostream_iterator<int>(std::cout, " "));
return 0;
}
|
I don't recommend inheritance from classes without a
virtual destructor. I use an overloaded operator << to
do this. If I have a custom container class I see no major
problem.
I prefer an overload of operator << to do this in general.
The only problem with a simple template solution like
template <class T,class A,class X>
inline
std::list<T,A> & operator << (std::list<T,A> &list,const X &x)
{
list.push_back(x);
return *this;
}
occurs if X is in namespace std, but this can be handle with a wrapper
struct containing a const X &.
template <class X>
struct class_wrapper
{
const X &x;
class_wrapper(const X & a) (a){}
operator const X &() {return x;}
};
template <class X>
inline class_wrapper<X> wrap_class(const X &x)
{ return class_wrapper<X>(x);}
and using wrap_class(x) as the args of the << chain.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Guest
|
Posted: Thu Jun 22, 2006 4:02 pm Post subject: Re: Using operator() as return a reference to class self |
|
|
Mockey Chen wrote:
....
| Quote: | There is an example:
....
template<typename T
class cmlist : public std::list<T
{
public:
// Note: here *MUST* return a reference to class self
cmlist& operator()(const T& e)
{
this->push_back(e);
return *this;
}
};
int main()
{
cmlist<int> il;
// Note: using recursive call operator to
// initialize the list.
// avoid using 3 line to call 3 push_back()
il(3)(4)(5);
return 0;
}
Any suggestion?
|
Yes - boost assignment library:
http://www.boost.org/libs/assign/index.html
It does what you are suggesting, using that trick and many more.
| Quote: | --
Regards.
Mockey Chen
|
Tony
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Joe Guest
|
Posted: Fri Jun 23, 2006 3:03 pm Post subject: Re: Using operator() as return a reference to class self |
|
|
Mockey Chen wrote:
| Quote: | Overload operator() is magic in C++, since you can implement
a functor using operator(), the behave like a normal function.
I found we can use a trick that operator() return a reference to
class self. According return value, we can do a recursive call
operator(), this idiom can be used to initialize a list like class,
such as list, deque, vector...
There is an example:
template<typename T
class cmlist : public std::list<T
{
public:
// Note: here *MUST* return a reference to class self
cmlist& operator()(const T& e)
{
this->push_back(e);
return *this;
}
};
|
Since the std collections aren't really designed to be publicly
inherited from, I would do one of two things. If I wanted my own types
that did what the std ones do with some extras, I would privately
inherit the class (this prevents someone from casting my class to the
std one and thinking that if they delete that class, my class would be
cleaned up too) and export the methods I wanted with a 'using'
statement. If I didn't want that, then I would write my class as a
wrapper which accepts a std collection as its initializer and then
initialized that. My wrapper could then disappear and the user would
use the std collection everywhere.
I haven't actually compiled this, but it might look like
template<typename C>
class InitializeIt {
public:
typedef InitializeIt<C> _Self;
typedef typename C::value_type value_type;
InitializeIt(C & c) : m_c(c) {}
_Self & operator()(value_type const & v) {
m_c.push_back(v);
return *this;
}
private:
C & m_c;
};
int main(int, char **)
{
std::list<int> l;
InitializeIt<std::list<int> > i(l);
i(5)(6)(6)( ;
std::copy(l.begin(),
l.end(),
std::ostream_iterator<int>(std::cout, " "));
}
This accomplishes the same thing without introducing a new set of
types.
Hope that helps,
joe
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|