Hi everybody!
While trying to implement a generic sorting function which takes a
member function(on which base the actual sort happens) as a parameter,
I have met the problem that I need to use the result type of the member
function and as I have understood there is no way in standart stl to
extract it. While searching through this groop and in general, I could
found some references to the problem in the following topic :
http://groups.google.com/group/comp.lang.c++/
browse_thread/thread/78677a3723145f8 8/d1f20e844962200 5?
q=extract+retur n+type+function &rnum=1#d1f20e8 449622005
and for example the reference on TR1 from Scott Meyers "Effective C++"
site:
http://aristeia.com/EC3E/TR1_info_frames.html. Where exists the class
"result_of" which takes the function as a template parameter and to get
the type is simply the following: result_of<funct ion>::type.
Does anybody know how far is TR1 integrated in stl and whether and how
the above functionaliry can be used,
or does boost or any other enhanced library have the above feature?
In order to show an idea where the generic extraction of function
result type can be used, there is an example with generic sorting
function:
Imagine we have a class Element:
--------------------------------------------
class Element {
public:
typedef int element_type;
typedef string name_type;
Element(const name_type& name, element_type a, element_type b) :
_name(name), _a(a), _b(b) {}
const name_type& getName() const { return _name; }
element_type getA() const { return _a; }
element_type getB() const { return _b; }
~Element() { }
private:
name_type _name;
element_type _a, _b;
};
--------------------------------------------
and class Alphabet which is a kind of container for Elements:
--------------------------------------------
class Alphabet {
public:
typedef Element element_type;
typedef vector<element_ type> container;
typedef container::size _type size_type;
Alphabet(const container& elements) : _elements(eleme nts) {}
~Alphabet() {}
size_type size() const { return _elements.size( ); }
template <typename T>
void sorting(T func_ptr); // the main point of interest
private:
container _elements;
}; // an example has minimal interface, using namespace ... are
omitted.
ostream& operator << (ostream& os, const Alphabet& alphabet) {
for (Alphabet::size _type i = 0; i < alphabet.size() ; ++i ) {
Alphabet::eleme nt_type element = alphabet.at(i);
os << element.getName () << ", " << element.getA() << ", " <<
element.getB() << endl;
}
return os;
}
// definition of Alphabet::sorti ng is further below
--------------------------------------------
The idea is to sort elements in Alphabet by giving an Element member
function as a sorting criteria. // another way would be to create
functors with different comparison function, but that what I would like
to avoid at the moment and see if this way could be elegant...
The example of main would be like this:
int main(int argc, char** argv) {
Element a("a", 2, 4), b("b", 3, 2), c("c", 4, 1), d("d", 1, 3);
vector<Element> els; // elements
els.push_back(a ); els.push_back(b ); els.push_back(c );
els.push_back(d );
Alphabet alphabet(els);
cout << "Alphabet before sort: " << alphabet << endl;
alphabet.sortin g(&Element::get Name);
cout << "Alphabet sorted on name: " << alphabet << endl;
alphabet.sortin g(&Element::get A);
cout << "Alphabet sorted on A: " << alphabet << endl;
alphabet.sortin g(&Element::get B);
cout << "Alphabet sorted on B: " << alphabet << endl;
return 0;
}
Which prints out elements in the alphabet depending on the sorting
criteria.
So the definition of sorting would be lke this (with the help of TR1
functionality):
template <typename T>
void Alphabet::sorti ng(T func_ptr) {
sort(_elements. begin(), _elements.end() ,
compose_f_gx_hy (
less<typename tr1::result_of( func_ptr)::type >(),
mem_fun_ref(fun c_ptr),
mem_fun_ref(fun c_ptr)));
}
where compose_f_gx_hy is taken from here:
-----------------------------------------------------------------------------
The following code example is taken from the book
The C++ Standard Library - A Tutorial and Reference
by Nicolai M. Josuttis, Addison-Wesley, 1999
© Copyright Nicolai M. Josuttis 1999
#include <functional>
/* class for the compose_f_gx_hy adapter
*/
template <class OP1, class OP2, class OP3>
class compose_f_gx_hy _t
: public std::binary_fun ction<typename OP2::argument_t ype,
typename OP3::argument_t ype,
typename OP1::result_typ e>
{
private:
OP1 op1; // process: op1(op2(x),op3( y))
OP2 op2;
OP3 op3;
public:
// constructor
compose_f_gx_hy _t (const OP1& o1, const OP2& o2, const OP3& o3)
: op1(o1), op2(o2), op3(o3) {
}
// function call
typename OP1::result_typ e
operator()(cons t typename OP2::argument_t ype& x,
const typename OP3::argument_t ype& y) const {
return op1(op2(x),op3( y));
}
};
/* convenience function for the compose_f_gx_hy adapter
*/
template <class OP1, class OP2, class OP3>
inline compose_f_gx_hy _t<OP1,OP2,OP3>
compose_f_gx_hy (const OP1& o1, const OP2& o2, const OP3& o3) {
return compose_f_gx_hy _t<OP1,OP2,OP3> (o1,o2,o3);
}
-----------------------------------------------------------------------------
(this function should be also in boost, but I haven't checked which
one)
Do you know whether such Alphabet::sorti ng definition works, and if yes
there is more beginner question: how to intergrate TR1 in the project?
Or is there something similar in boost library?
By the way, I have already tried to implement Alphabet::sorti ng without
templates (say for only a certain types of function, in the above
example there were : Element::getA and Element::getB) and that worked
just fine. Would be nice to get more generic solution working.
Any ideas are appreciated.
kind regards,
Anton Pervukhin