1

The Example class is shown below:

class Example
{
public:
    Example(): x_(0) {}    // problematic constructor
    Example(int x = 1): x_(x){}    // not problematic constructor

    int getX() { return x_; }
private:
    int x_;
};

Testing out Example in main:

int main()
{
    // problem with this constructor
    Example example1;
    auto x1 = example1.getX();

    // no problem with this constructor
    Example example2(500);
    auto x2 = example2.getX();
}

Issue Solved:

Eliminate constructor ambiguity by removing the default parameter values in the 2nd constructor. The constructors would look as follows:

    Example(): x_(0) {}    
    Example(int x): x_(x){}    

This would not violate the rules of cpp constructor overloading that lead to ambiguity.

MShakeG
  • 391
  • 7
  • 45
  • 2
    Do things improve if you change the second line to `Shooter shooter1(500, 700, up);` ? – Jeremy Friesner Aug 24 '19 at 13:22
  • @JeremyFriesner it's still the same – MShakeG Aug 24 '19 at 13:24
  • @IronProgrammer Provide a minimal complete program that reproduces the error. – Vlad from Moscow Aug 24 '19 at 13:25
  • I think you'll need to post enough code that people can compile it locally; as it is, there is no way for anyone to test for themselves. – Jeremy Friesner Aug 24 '19 at 13:25
  • or at least show us the 'Shooter' class – Memos Electron Aug 24 '19 at 13:26
  • Why not use braces to avoid the possibility of a [Most Vexing Parse](https://en.wikipedia.org/wiki/Most_vexing_parse)? I.e. `Shooter shooter1{500, 700, up};` – Michael Aug 24 '19 at 13:28
  • 2
    The problematic line should be: `Shooter shooter1(500, 700, up);` // **no more problem** – Phil1970 Aug 24 '19 at 13:35
  • Wherever you saw an example of code that passes types and parameter names when creating an object, you should stay far away from there. – molbdnilo Aug 24 '19 at 13:48
  • On something similar I did, I am getting this error: `call of overloaded ‘Shooter()’ is ambiguous Shooter shooter;` and this error: `error: request for member ‘getSprite’ in ‘shooter1’, which is of non-class type ‘Shooter(int, int`. – Memos Electron Aug 24 '19 at 13:48
  • 1
    So maybe you missed that you have more than 1 error – Memos Electron Aug 24 '19 at 13:51
  • 2
    Since nobody has said so explicitly: you have two constructors that can be used without arguments, which is ambiguous, and your second declaration declares a function. There is a list of good books [here](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – molbdnilo Aug 24 '19 at 14:20
  • @IronProgrammer The second error is a direct consequence of the first error (compiler think that you have declared a function `sprite1`). If you correct that, you will get an ambiguity since you will have 2 possibles constructors with no argument. Probably the best solution would be to remove the parameter less constructor. Alternatively, if it make more sense, you can remove default value for `x`. – Phil1970 Aug 24 '19 at 17:00
  • @molbdnilo I removed the default constructor and it worked, however I don't see why it would be ambiguous as there wasn't a problem with the constructor overloading. – MShakeG Aug 27 '19 at 21:11
  • overloading and calling overloaded functions are different things. You may define two unequal functions, but then you can form a call that cannot be resolved in favor of either of them (e.g. because both can be used with same amount of implicit type casts) – Swift - Friday Pie Apr 04 '20 at 22:22

1 Answers1

0

Default value for argument makes call to default constructor ambiguous. Which function this would call, the first constructor, or the second one?

    Example example1 = Example(); // equivalent of Example example1;

Only solution is not to form such declarations. Constructor with all arguments defaulted is equal to constructor with no arguments.

class Example
{
public:
    Example(int x = 0): x_(x){}    // same as default constructor

    int getX() { return x_; }
private:
    int x_;
};
Swift - Friday Pie
  • 12,777
  • 2
  • 19
  • 42