?
Solved

Using a STL function object to 'multiply' a STL list of my C++ classes.

Posted on 2003-03-27
5
Medium Priority
?
329 Views
Last Modified: 2008-02-01
Hi,
I'm learning STL (Standard template library)
and am finding all the text books very frustrating.
The all use primitive types sich as 'int's as the objects
held in containrs. The usefullness rearly comes when you
use containers on your own classes. This is what i'm
trying to do in the example below. The second 'accumulate'
in the program below does not compile with error C2679
I have attempted to give my class all the 'operators'
I can think of. PLEASE tell me how to do this task.

#include "stdafx.h"

using namespace std;

class CBlob
{
public:

    int     ia;
    long    lb;
    char    cc;

public:

    CBlob() : ia(0) , lb(0L) , cc('a') { };
    CBlob(int a,long b,char c) : ia(a) , lb(b) , cc(c) { };
    virtual ~CBlob () { };

    CBlob::CBlob (const CBlob& rh)      // Copy Constructor
    {
        ia = rh.ia;
        lb = rh.lb;
        cc = rh.cc;
    };

    CBlob& operator + (const CBlob& rh)
    {
        ia += rh.ia;
        lb += rh.lb;
        cc  = 'P';
        return *this;
    };

    CBlob& operator + (const int rh)
    {
        ia += rh;
        lb += rh;
        cc  = 'I';
        return *this;
    };

    CBlob& operator += (const CBlob& rh)
    {
        ia += rh.ia;
        lb += rh.lb;
        cc  = '=';
        return *this;
    };

    CBlob& operator += (const int rh)
    {
        ia += rh;
        lb += rh;
        cc  = 'I';
        return *this;
    };

    CBlob operator() (const CBlob& x, const CBlob& y) const
    {
        CBlob tmp;
        tmp.ia = x.ia+y.ia;
        tmp.lb = x.lb+y.lb;
        tmp.cc = 'X';
        return tmp;
    };

    CBlob& operator = (const CBlob& rh)
    {
        ia = rh.ia;
        lb = rh.lb;
        cc = rh.cc;
        return *this;
    };

    bool operator < (const CBlob& rh)
    {
        if (ia < rh.ia)
        {
            return true;
        }
        else if (ia == rh.ia)
        {
            return (lb < rh.lb);
        }
        return false;
    };

    bool operator >= (const CBlob& rh)
    {
        return false;
    };
};

int main(int argc, char* argv[])
{
    CBlob a(1,100l,'A');
    CBlob b(2,200l,'B');
    CBlob c(3,300l,'C');
    CBlob sum;

    int x[5] = {2,3,5,7,11};

    std::vector < int > v1(x,x+5);

    // This call compiles ok.
    int prod = accumulate (v1.begin(),v1.end(),1,multiplies <int>());

    list < CBlob > lst;
    list < CBlob > ::iterator i;

    lst.push_front (a);
    lst.push_front (b);
    lst.push_front (c);

    lst.reverse ();

    // THs fommowing line of code errors with:
    // error C2679: binary '=' : no operator defined which takes a right-hand operand of type 'int' (or there is no acceptable conversion)

    sum = accumulate (lst.begin(), lst.end() , 1 , multiplies<CBlob>());

    for (i = lst.begin() ; i != lst.end() ; i++)
    {
        CBlob tmp = *i;

        //cout << "ia=" << tmp.ia << ",  lb=" << tmp.lb << ",  cc=" << tmp.cc << "\n" << flush;
    }
     return 0;
}

0
Comment
Question by:mellor
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
5 Comments
 
LVL 6

Expert Comment

by:GaryFx
ID: 8218640
The return type of the accumulate function is the same as the type of its third argument.  In this case, you're passing the integer 1 as the third argument, so accumulate returns an int.  However, you haven't defined an operator= for assigning an int to a CBlob, nor have you defined any other way to convert an int to a CBlob (e.g. a constructor CBlob(int) or a typecast operator).

Once you get past that part, the multiplies functor uses the binary * operator, but you haven't defined that for CBlob either.

Gary
0
 
LVL 1

Expert Comment

by:fsign21
ID: 8218646
The problem, I can see is the 3 argument in accumulate.
sum = accumulate (lst.begin(), lst.end() , 1 , multiplies<CBlob>());

The 3 argument should be of type CBlob.
You use 1, so the compiler tries to find a constructor, which  takes only int argument, which you did not provide.

Try
sum = accumulate (lst.begin(), lst.end() , CBlob(1,100l,'A') , multiplies<CBlob>());


0
 

Author Comment

by:mellor
ID: 8221118
Thanks to you both,
I'm making progress. Now I have to supply a '*'
operator. I've tried many 'const' and non 'const'
variations, three examples are:

    CBlob& operator * (const CBlob rh)
    {
        ia *= rh.ia;
        lb *= rh.lb;
        cc  = '*';
        return *this;
    };

    CBlob& operator * (const CBlob& rh)
    {
        ia *= rh.ia;
        lb *= rh.lb;
        cc  = '*';
        return *this;
    };

    CBlob& operator * (const int rh)
    {
        ia *= rh;
        lb *= rh;
        cc  = '*';
        return *this;
    };

All generate compiler message:
error C2678: binary '*' : no operator defined which takes a left-hand operand of type 'const class CBlob'

Could someone please show me how to give this
'accumulate' template the '*' operator it requires!
If there was a good STL text book I would not have
to be asking these simple quesions.
(or I had some more brain cells!!!)
Yours
Allan
0
 
LVL 6

Accepted Solution

by:
GaryFx earned 680 total points
ID: 8222659
The best STL textbook is The C++ Standard Library: A Tutorial and Reference by  Nicolai M. Josuttis, Addison-Wesley, 1999.

I don't have my references handy right now, but I think you're doing the operator * wrong.  You have it changing the lhs, which isn't the way the binary math operators should work.  I don't think there's any way to avoid creating a new object with the binary operators and still have them work the way they're expected to work.

Try instead

CBlob operator* (const CBlob& rh) const {
   CBlob result;
   result.ia = ia*rh.ia;
   result.lb = lb*rh.lb;
   result.cc = '*';
   return result;
}
0
 

Author Comment

by:mellor
ID: 8237307
Thanks GaryFx,
I'll be getting that book.
Yours
Allan
0

Featured Post

Get real performance insights from real users

Key features:
- Total Pages Views and Load times
- Top Pages Viewed and Load Times
- Real Time Site Page Build Performance
- Users’ Browser and Platform Performance
- Geographic User Breakdown
- And more

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Navigation is an important part of web design from a usability perspective. But it is often a pain when it comes to a developer’s perspective. By navigation, it often means menuing. This is less theory and more practical of how to get a specific gro…
There is an easy way, in .NET, to centralize the treatment of all unexpected errors. First of all, instead of launching the application directly in a Form, you need first to write a Sub called Main, in a module. Then, set the Startup Object to th…
The viewer will learn how to implement Singleton Design Pattern in Java.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
Suggested Courses

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question