compile time error

Discussion in 'C++' started by heidik, Nov 16, 2010.

  1. heidik

    heidik New Member

    Joined:
    Oct 23, 2010
    Messages:
    69
    Likes Received:
    0
    Trophy Points:
    0
    I have a function called compr


    Code:
    bool class1::compr(const structT1& t1, const structT1& t2)
    {          
        return t1.dateTime > t2.dateTime;
    }
    
    and I am using it for sorting a vector on the basis of time

    Code:
    std::sort(vecT1->begin(), vecT1->end(), compr);
    it is giving me an error which is as follows

    Code:
    error: argument of type ‘bool (class1::)(const class1::structT1&, const class1::structT1&)’ does not match ‘bool (class1::*)(const class1::structT1&, const class1::structT1&)’
    I am compiling this program on Linux

    Could anyone please help
     
  2. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    With this kind of error I find it helpful to line the two things it can't match against each other so it becomes clearer exactly what the problem is:
    Code:
    error: argument of type ‘
    bool (class1:: )(const class1::structT1&, const class1::structT1&)’ does not match ‘
    bool (class1::*)(const class1::structT1&, const class1::structT1&)’
    
    OK, so the difference is a *, so it's getting a pointer where it's expecting an object or reference, or vice versa. Could it be that vecT1->begin() returns a pointer, but compr takes references?
     
  3. heidik

    heidik New Member

    Joined:
    Oct 23, 2010
    Messages:
    69
    Likes Received:
    0
    Trophy Points:
    0
    Thanks xpi0t0s. I searched for the error on google and added the keyword static to the compr declaration (not definition) and it worked fine. But still thanks :)
     
  4. heidik

    heidik New Member

    Joined:
    Oct 23, 2010
    Messages:
    69
    Likes Received:
    0
    Trophy Points:
    0
    Hello xpi0t0s. Could you please have a look at my problem.

    I want to find out all the matches (could be more than two) between itFirst and itCurrent i-e all matches in the vector my_file_as_blocks. Could you please tell me how/where do I increment/change_value_of the itFirst? OR how/where do I match each value of itCurrent with itFirst?

    Code:
    			std::vector<block>::const_iterator itFirst   = my_file_as_blocks.begin();    // inner loop
    			std::vector<block>::const_iterator itCurrent = my_file_as_blocks.begin();    // outer loop
    			std::vector<block>::const_iterator itEnd     = my_file_as_blocks.end();
    
    		    	int gpID = 0;
    		    	int prevgpID = 0;
    		    	int subGpID = 0;
    		    	string prevLineID = "";
    		    	string newLineID = "";
    
        			for ( ; itCurrent != itEnd ; ++itCurrent )
            		{
                			if ( itFirst != itCurrent )
                			{
            				// if order IDs match
            				if ( (itFirst->id1 == itCurrent->id1 && itFirst->id2 == itCurrent->id2) || (itFirst->id1 == itCurrent->id2 && itFirst->id2 == itCurrent->id1) )
                    			{
                					newLineID = itFirst->lineID;
    						
                					if((itFirst->last_line.find("2nd-ORD") != std::string::npos ) && (itCurrent->last_line.find("2nd-ORD") != std::string::npos ))
                					{      
    
                    					// if same group
                    					if(prevLineID == newLineID)
                    					{   
                        						subGpID++; // only increase the sub-group Group IDs
                    					}
                    					else
                    					{    // else add one to the gpID as newLineID changes, subGpID is reset, prevLineID is again made equal to newnewLineID
    							    gpID++;   
    							    subGpID = 0;
    							    prevLineID = newLineID;
    	
    							    cout << "================================" << std::endl;
    							    std::cout << "Found a match:" << std::endl;
    							    cout << "================================" << std::endl;                   
                       
    							    std::cout << "Block with \n----------\nalert ID: " << itFirst->lineID << "\norder ID: " << itFirst->id1 << "\norder ID: " << itFirst->id2 << std::endl;
    							    cout << "--------------------" << endl;
    							    cout << itFirst->lineID << ":0:Order Group:" << gpID << ":0" << endl;
    							    cout << "--------------------" << endl;
                    					}
    
                        				std::cout << "\nhas a match with \n--------------------\nalert ID: " << itCurrent->lineID << "\norder ID: " 
    						<< itCurrent->id1 << "\norder ID: " << itCurrent->id2 << std::endl;
    					    	cout << "--------------------" << endl;
    					    	cout << itFirst->lineID << ":0:Order Group:" << gpID << ":" << subGpID+1 << endl;
    					    	cout << "--------------------" << endl;
                       
                        				std::cout << "================================" << std::endl;
                            			std::cout << "End match" << std::endl;
                        				std::cout << "================================" << std::endl << std::endl << std::endl;
    
               				} // end of IF for existence of "2nd-ORD"
                				else
                				{               
                           				???? //itFirst = itCurrent; // in case itFirst and itCurrent do not match
                				}
    
                    		} // end of IF for comparing order IDs
                    		else
                    		{
                        			??? //itFirst = itCurrent; // in case itFirst and itCurrent do not match
                    		}
                		} // end of if ( itFirst != itCurrent )
    
     
  5. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    Bit tricky when I don't know what the code is supposed to do. But if you are looking for duplicates, say in a set containing ABCDE, then you'll need to compare A with BCDE, B with ACDE, C with ABDE etc, so for that you would need nested for loops, each looping over ABCDE with a check for not comparing the same element, or for a slightly more optimal search perform the outer loop O from A-D(not E), then the inner loop from O+1 to E, i.e. AB AC AD AE, BC BD BE, CD CE, DE: 10 comparisons instead of 20.

    Translating that into your domain then, if itO is the outer loop iterator and itI the inner:
    Code:
    std::vector<block>::const_iterator itO = my_file_as_blocks.begin();
    for (; itO!=end-1; itO++)
    {
      std::vector<block>::const_iterator itI= // some way of initialising itI to itO+1, maybe =itO; itI++;
      for (; itI; itI++)
      {
        if (itFirst->id1 == itCurrent->id1 etc) { ... }
      }
    }
    
    Or for the less optimal if you can't be bothered filling in the gaps:
    Code:
    std::vector<block>::const_iterator itO = my_file_as_blocks.begin();
    for (; itO; itO++)
    {
      std::vector<block>::const_iterator itO = my_file_as_blocks.begin();
      for (; itI; itI++)
      {
        if (itI!=itO)
        {
          if (itFirst->id1 == itCurrent->id1 etc) { ... }
        }
      }
    }
    
    Better still, avoid the problem altogether when you add elements to the vector by checking if a new element already exists first. At the moment you just read the lot into the vector unconditionally, so instead if you want to eliminate duplicates, instead of doing
    Code:
    vec.push_back(new_elem);
    
    you would do
    Code:
    if (!vec.contains(new_elem))
      vec.push_back(new_elem);
    
    But it depends on when you want to eliminate the duplicates and if you need to process the vector WITH duplicates after reading it in, before eliminating the dups.
     
    shabbir likes this.
  6. heidik

    heidik New Member

    Joined:
    Oct 23, 2010
    Messages:
    69
    Likes Received:
    0
    Trophy Points:
    0
    Actually I am reading from a file and that file contains duplicate blocks of data and I just have to point out the blocks which are duplicates of each other. I do not have to remove them. I just have to find out. And also there can be more than just one duplicate of any block. Some of the data blocks have even 10 or more duplicate blocks and I have to find them all and display the msg on the screen. Could you please help?
     
  7. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    Well, I just did. Any of the approaches I outlined can be used to spot, remove or otherwise process duplicates.
     
  8. heidik

    heidik New Member

    Joined:
    Oct 23, 2010
    Messages:
    69
    Likes Received:
    0
    Trophy Points:
    0
    The loops above turn into never ending loops ;'( cant figure out why. I have written a very simple program and I want something like this though I havent tried it for solving the actual problem

    Code:
    struct MyPred
    {
        std::string x;
        std::string a;
        std::string y;
        std::string z;
    
        MyPred(const std::string& x, const std::string& a, const std::string& y, const std::string& z): x(x), a(a), y(y), z(z) {}
    
        bool operator==(const MyPred& p) const
        {
            return x == p.x && a == p.a && y == p.y && z == p.z;
        }
    
        bool operator<(const MyPred& p) const
        {
            if(x < p.x) return true;
            if(x > p.x) return false;
            if(y < p.y) return true;
            if(y > p.y) return false;
            if(z < p.z) return true;
            if(z > p.z) return false;
            return false;
        }
    };
    
    
    int main()
    {
        std::vector<MyPred> vPred;
        vPred.push_back(MyPred("a", "1", "a", "c"));
        vPred.push_back(MyPred("a", "2", "b", "b"));
        vPred.push_back(MyPred("a", "2", "a", "c"));
        vPred.push_back(MyPred("b", "3", "a", "c"));
        vPred.push_back(MyPred("a", "0", "b", "b"));
        vPred.push_back(MyPred("b", "6", "b", "h"));
        vPred.push_back(MyPred("b", "4", "b", "h"));
        vPred.push_back(MyPred("b", "9", "b", "h"));
    
        // The values need to be in order for equal_range() to work
        std::sort(vPred.begin(), vPred.end());
    
        std::pair<std::vector<MyPred>::iterator, std::vector<MyPred>::iterator> ret;
    
        for(std::vector<MyPred>::iterator i = vPred.begin(); i != vPred.end(); i = ret.second)
        {
            std::cout << "[" << i->x << ", " << i->a << ", " << i->y << ", " << i->z << "] => ";
            ret = std::equal_range(i, vPred.end(), *i);
            for(std::vector<MyPred>::iterator j = ret.first; j != ret.second; ++j)
            {
                std::cout << "[" << j->x << ", " << j->a << ", " << j->y << ", " << j->z << "]";
            }
            std::cout << '\n';
        }
    }
     
  9. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    The example at http://www.cplusplus.com/reference/stl/vector/end/
    uses iterator < end, rather than iterator != end. Maybe that's the problem?

    Try it out in a test program. Create a vector of strings and push into it the strings "Hello" and "World". Create an iterator and iterate over the vector displaying the results. It should display, depending on how you format the output, something along the lines of "Hello World". Try both forms "<end" and "!=end" and see what works.
     
  10. heidik

    heidik New Member

    Joined:
    Oct 23, 2010
    Messages:
    69
    Likes Received:
    0
    Trophy Points:
    0
    alright xpi0t0s thanks. Let me try this :)
     
  11. heidik

    heidik New Member

    Joined:
    Oct 23, 2010
    Messages:
    69
    Likes Received:
    0
    Trophy Points:
    0
    xpi0t0s it is working but it is not matching each block with all other blocks in one iteration ;'(. There are many blocks which are duplicates to the one that is being checked for matches but they are not found out in that particular iteration i-e not in one go ;'(. e-g

    matches for block-1: x y z
    matches for block-2: a b c
    then again
    matches for block-1: m n o
     
  12. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    Can you get the problem to reproduce with a simple test program, maybe one that just uses a vector of strings with some duplicates?
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice