0
#include<iostream>
#include<vector>
#include<algorithm>
class Integer
    {
public:
    int m;
    Integer(int a):m(a){};
    };
class CompareParts
    {
    public:
        bool operator()(const Integer & p1,const Integer & p2)
            {
            return p1.m<p2.m;
            }
    }obj1;
int main()
    {
    std::vector<Integer> vecInteger;
    vecInteger.push_back(Integer(12));
    vecInteger.push_back(Integer(13));
    vecInteger.push_back(Integer(5));
    vecInteger.push_back(Integer(7));
    vecInteger.push_back(Integer(9));
    Integer obj2();
    std::sort(vecInteger.begin(),vecInteger.end(),obj1);
    std::sort(vecInteger.begin(),vecInteger.end(),obj2);
    }

why is obj2 in second sort function leads to compiler error.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
yesraaj
  • 46,370
  • 69
  • 194
  • 251
  • 1
    Be sure to add the compile error to the question. That will help diagnose the problem. – nathan Aug 19 '09 at 14:27
  • "Sort function does not with function object created on stack?" You're missing a word in the title. I had to click through to see you meant COMPILE rather than WORK. – Pod Aug 19 '09 at 14:28

5 Answers5

15

Integer obj2() isn't the definition of an object, it is the declaration of a function named obj2 returning an Integer (put it outside any function to understand why it is so). This occurs also sometimes with more complex constructions where it can be even more confusing. Some name this the most vexing parse.

Here is the promised example of a more complex case:

struct Foo {};
struct Bar { Bar(Foo); };

Bar quxx(Foo()); // quxx is a function

Here quxx is a function returning a Bar and taking (a pointer) to a function returning a Foo and without parameters. You could write the same declaration more clearly like this:

Bar quxx(Foo (*fn)()); // quxx is the same function as above

To get the definition of a variable initialized with the constructor taking a Foo, you can add a level of parenthesis:

Bar quux((Foo())); // quux is a variable
legends2k
  • 31,634
  • 25
  • 118
  • 222
AProgrammer
  • 51,233
  • 8
  • 91
  • 143
  • 5
    Yes, and the correct syntax is "Integer obj2;". Add to that the fact that you probably wanted to create a CompareParts object, and you should be closer to results. – Kim Gräsman Aug 19 '09 at 14:30
  • 1
    Um, sure it's right. The point where a declaration appears is not necessary the point where the entity it declares lives. In this case, it declares a global function, using a local declaration. – Johannes Schaub - litb Aug 19 '09 at 14:31
  • 1
    AProgrammer is correct - it's a function declaration. And yes, you cn declare a function inside another function. –  Aug 19 '09 at 14:31
  • 2
    @Chickencha C++ takes from C the overriding rule that if something can possibly be parsed as a declaration, it will be parsed as a declaration. –  Aug 19 '09 at 14:33
  • @Chickencha, it is a *declaration* not a *definition*. It is quite old fashioned and you'll rarely see that in C++ and in modern C, but it is still valid and quite common in older code. AFAIR the 1st ed of K&R used it for instance. – AProgrammer Aug 19 '09 at 14:34
  • Okay, after looking into this a little more you guys are right. (Comments deleted to prevent misguiding people.) I could've sworn that I've seen instances of classes declared this way, but apparently not. Oh well, I learned something new today. – Evan Shaw Aug 19 '09 at 14:39
  • 1
    Some comment from the Standard: `8.5 Initializers /8`: *"[Note: since **`()`** is not permitted by the syntax for initializer, **`X a();`** is not the declaration of an object of class **`X`**, but the declaration of a function taking no argument and returning an **`X`**. The form **`()`** is permitted in certain other initialization contexts (5.3.4, 5.2.3, 12.6.2). ]"* Hope that explains the matter. – Johannes Schaub - litb Aug 19 '09 at 14:42
  • 1
    To complement litb comment: 5.3.4 -> new X(), 5.2.3 -> in an expression, says X x = X(), -> 12.6.2 -> in initialization list. About the case of an expression, note that the use in subexpressions in other constructors calls can lead to the ambiguity and the choice of a function declaration instead of a variable definition. I'll add an example. – AProgrammer Aug 19 '09 at 14:46
  • @Neil, well both versions are declarations. You may stick "extern" in front of it, and would get a non-defining object declaration if it weren't a function. The reason for this is, that there is no ambiguity at all. It's just a function declaration, not anything else. – Johannes Schaub - litb Aug 20 '09 at 11:39
3

Because obj2 is a function. See this

Community
  • 1
  • 1
Tadeusz Kopec for Ukraine
  • 12,283
  • 6
  • 56
  • 83
1

obj2 is not a BinaryPredicate and is invalid as the third parameter to std::sort

obj2 needs to be something like

// Return whether first element is greater than the second
bool UDgreater ( int elem1, int elem2 )
{
   return elem1 > elem2;
}

or the functor type used by obj1.

Jeff Leonard
  • 3,284
  • 7
  • 29
  • 27
1

There is no definition of no argument constructor.

Use, Integer obj2(0);

#include<iostream>
#include<vector>
#include<algorithm>
class Integer
{
     public:
     int m;
     Integer(int a):m(a){};
     bool operator()(const Integer p1,const Integer p2)
     {
      return p1.m<p2.m;
     }
};
class CompareParts
{    public:
     bool     operator()(const Integer  p1,const Integer p2)
     {
         return p1.m<p2.m;
         }
}obj1;

int main()
{
    std::vector<Integer> vecInteger;
    vecInteger.push_back(Integer(12));
    vecInteger.push_back(Integer(13));
    vecInteger.push_back(Integer(5));
    vecInteger.push_back(Integer(7));
    vecInteger.push_back(Integer(9));
    Integer obj2(0);
    std::sort(vecInteger.begin(),vecInteger.end(),obj1);
    std::sort(vecInteger.begin(),vecInteger.end(),obj2);

    return 0;
}
KV Prajapati
  • 93,659
  • 19
  • 148
  • 186
0
#include<iostream>
#include<vector>
#include<algorithm>

class Integer
{
public:
int m;
Integer(int a):m(a){};
};

class CompareParts {
public:
bool operator()(const Integer & p1,const Integer & p2)
{
return p1.m }
};

int main()
{
std::vector vecInteger;
vecInteger.push_back(Integer(12));
vecInteger.push_back(Integer(13));
vecInteger.push_back(Integer(5));
vecInteger.push_back(Integer(7));
vecInteger.push_back(Integer(9));

std::sort(vecInteger.begin(),vecInteger.end(),CompareParts()); 
typedef vector<Integer>::const_iterator Iter;
Iter beg = vecInteger.begin();
Iter end = vecInteger.end();

for (Iter iter = beg; iter != end; ++iter)
    cout << (*iter).m << " ";

cout << endl;

}

Output: 5 7 9 12 13

Jagannath
  • 3,995
  • 26
  • 30