Re: Using operator() as return a reference to class self
Mockey Chen wrote:
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)(8);
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! ]