-1

I wrote below code but getting error message

call of overloaded 'Shape()' is ambiguous

As I can see there is a no argument constructor, then why I am getting ambiguity error message for Shape() constructor, and how it can be resolved? I can see its working for object s2 and s3 but not for no argument constructor.

When I am declaring s1 as follows:

Shape s1(); // instead of Shape s1

Then I am getting following message for print method of Shape. Why? and what is meant by non-class type?

request for member 'print' in 's1', which is of non-class type 'Shape()'

class Shape {

    int j;

    public:
        int i;
        const char* const c;

        double print() const {
            printf("Value of i is %d, j is %d and c is %s\n", i, j, c);
            return 0;
        }

        Shape() :
                i(10), j(0), c("Some string") {
        }
        Shape(int i = 10) :
                i(10), j(10), c("Some String") {
            this->i = i;
        }

        Shape(char* c) :
                i(), j(), c(strcpy(new char[strlen(c)], c)) {
        }
};

int main() {
    Shape s1; // call of overloaded 'Shape()' is ambiguous

    Shape* s2 = new Shape(1);

    Shape s3("Some string");

    s1.print(); // When using Shape s1() I am getting request for 
                // member 'print' in 's1', which is of non-class type 'Shape()'

    return 0;
}
Vishrant
  • 15,456
  • 11
  • 71
  • 120
  • 2
    Any idea what this means? `Shape(int i = 10)` – juanchopanza Feb 05 '17 at 19:04
  • 2
    You might want to read this: http://stackoverflow.com/questions/1424510/most-vexing-parse-why-doesnt-a-a-work – Rakete1111 Feb 05 '17 at 19:04
  • @juanchopanza - it is an argument with a default value. If no argument is given, it will be considered as if 10 was passed. But not here, of course, since he also had a constructor with no arguments. – yakobom Feb 05 '17 at 19:07
  • 1
    @yakobom I wasn't asking you. – juanchopanza Feb 05 '17 at 19:08
  • @juanchopanza these are the default param, like we do have in method declaration in c++. – Vishrant Feb 05 '17 at 19:20
  • @Vishrant Very good. And what does the default parameter allow you to do? – juanchopanza Feb 05 '17 at 19:21
  • if I am not passing anything in method/ constructor call it will assign the default values. – Vishrant Feb 05 '17 at 19:24
  • @juanchopanza I understand that c++ is getting two valid constructors to call. buy why? In Java this is not the case. Here it is violating the method signature and calling constructor with default values. Also why I am getting `member 'print' in 's1', which is of non-class type 'Shape()'` – Vishrant Feb 05 '17 at 19:29
  • To answer your other question, `Shape s1();` declares a **function** named `s1` that takes no arguments and returns an object of type `Shape`. – Pete Becker Feb 05 '17 at 19:33
  • @PeteBecker please elaborate, I did `Shape s1() { return Shape(10); }` but could not see any impact still the same message `member 'print' in 's1', which is of non-class type 'Shape()'` – Vishrant Feb 05 '17 at 19:37
  • @juanchopanza I understood my first question. but not the other one. `member 'print' in 's1', which is of non-class type 'Shape()'` – Vishrant Feb 05 '17 at 19:39
  • You were already told that is because you declared a function. Please read the comments and answers carefully. – juanchopanza Feb 05 '17 at 19:40
  • @Vishrant - when `s1` is the name of a function it's not the name of an object. You can't call member functions on it, just like you can't call member functions on `strcpy`. – Pete Becker Feb 05 '17 at 19:41

2 Answers2

3

The problem is it can't figure out whether to call Shape(int i = 10) with i = 10 or Shape()

Shape s1; could be Shape(10); (second one) or Shape(); (first one)

either remove the default input on the second constructor (replace i = 10 -> with i or remove the first constructor

  • Thanks, please also elaborate why I am getting `member 'print' in 's1', which is of non-class type 'Shape()'` – Vishrant Feb 05 '17 at 19:31
2

This happens because you have two applicable constructors: one without an argument and one with an argument, that also has a default value.
If you got 2 constructors, both of which could be called, which one should the compiler call? Obviously the compiler doesn't know and tells you that your call to the constructor is ambiguous.

To solve this you need to disambiguate the constructors by either removing the default value on the second constructor, passing the value explicitly or removing one of the constructors.

tambre
  • 4,625
  • 4
  • 42
  • 55