Thread: template method

  1. #1
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937

    template method

    Hello,
    I have two functions that operate in much the same way on two different kinds of vectors.

    if we allow
    Code:
    typedef pair<num_t, num_t> point;
    then
    one operates on
    Code:
    vector<   pair< point , vector<point> >   >
    and the other operates on
    Code:
    vector< span >
    where
    Code:
    struct span
    {
        num_t x;
        num_t dy;
    }
    //It's essentially a pair, but I didn't want the 'first' and 'second' syntax.
    So the first function does something involving vec[i].dy, and the other does the same thing using vec[i].second.size(), both for each element of vec.

    How can I write these two as one general function, without the use of helper classes? The functions are small enough that writing it twice is not so horrible, but if there is a straightforward template method, that'd be better.

    Thanks.
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Why not show what you have written for each of the types involved?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    For brevity. Here you go:
    Code:
    //. . . somewhere in the class grid:
    struct span;
    typedef std::vector<span> region;
    typedef std::pair< point2d, std::vector<point2d> > normal_pair;
    typedef std::vector<normal_pair> boundary;
    then here are a couple of examples

    Code:
    grid::size_type num_points(const grid::region & r, unsigned int until)
    {
    	unsigned long int points = 0;
    	for(unsigned int i = 0; i < r.size() && i < until; ++i)
    		points += r[i].dy;
    	return points;
    }
    
    grid::size_type num_points(const grid::boundary & b, unsigned int until)
    {
        unsigned long int points = 0;
    	for(unsigned int i = 0; i < b.size() && i < until; ++i)
    		points += b[i].second.size();
    	return points;
    }
    
    grid::size_type first_more_than(const grid::region & reg, unsigned long int quota, grid::size_type begin_index)
    {
    	unsigned long int count = 0;
    	for(unsigned int i = begin_index; i < reg.size(); ++i)
    	{
    		count += reg[i].dy;
    		if(count > quota)
    			return i;
    	}
    	return reg.size();
    }
    
    grid::size_type first_more_than(const grid::boundary & bound, unsigned long int quota, grid::size_type begin_index)
    {
        unsigned long int count = 0;
    	for(unsigned int i = begin_index; i < bound.size(); ++i)
    	{
    		count += bound[i].second.size();
    		if(count > quota)
    			return i;
    	}
    	return bound.size();
    }
    Using custom functors in stl algorithms would do the trick, but is there a way to specify a member?
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  4. #4
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    I guess I could just overload a function thing_to_count(vector), and then have the other functions use that one.
    Code:
    inline unsigned long thing_to_count(boundary::const_reference ref) { return b.second.size(); }
    inline unsigned long thing_to_count(region::const_reference ref) { return r.dy; }
    
    template<class vec_T>
    grid::size_type num_points(const vec_T & v, unsigned int until)
    {
           unsigned long int points = 0;
    	for(unsigned int i = 0; i < b.size() && i < until; ++i)
    		points += thing_to_count(v[i]);
    	return points;
    }
    
    template<class vec_T>
    grid::size_type first_more_than(const vec_T & v, unsigned long int quota, grid::size_type begin_index)
    {
    	unsigned long int count = 0;
    	for(unsigned int i = begin_index; i < reg.size(); ++i)
    	{
    		count += thing_to_count(v[i]);
    		if(count > quota)
    			return i;
    	}
    	return reg.size();
    }
    It actually looks good to me.
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  5. #5
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    That looks like a sensibl solution to me.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Specialising a member function with a template template parameter
    By the4thamigo_uk in forum C++ Programming
    Replies: 10
    Last Post: 10-12-2007, 04:37 AM
  2. matrix class
    By shuo in forum C++ Programming
    Replies: 2
    Last Post: 07-13-2007, 01:03 AM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  4. error: template with C linkage
    By michaels-r in forum C++ Programming
    Replies: 3
    Last Post: 05-17-2006, 08:11 AM
  5. oh me oh my hash maps up the wazoo
    By DarkDays in forum C++ Programming
    Replies: 5
    Last Post: 11-30-2001, 12:54 PM