Function overloading — two functions only differ by a default parameter

旧街凉风 提交于 2019-12-05 00:16:53

问题


class A{
    public:
        void foo(int x)
        {
            cout << "foo with one\n";
        }

        void foo(int x, int y=10)
        {
            cout << "foo with two\n";
        }
};

int main()
{
    A a;
    a.foo(1);   //error?
}

So, why can't I overload void foo(int) with a function that takes a default parameter?


回答1:


No you cannot overload functions on basis of value of the argument being passed, So overloading on the basis of value of default argument is not allowed either.

You can only overload functions only on the basis of:

  • Type of arguments
  • Number of arguments
  • Sequence of arguments &
  • Qualifiers like const and volatile.

Ofcourse, Whether the overload is accepted by the compiler depends on the fact:
If the compiler resolve calling of the function unambiguously.

In your case, the compiler cannot resolve the ambiguity, for ex: The compiler wouldn't know which overloaded function to call if you simple called the function as:

 foo(100);

The compiler cannot make the decision and hence the error.




回答2:


No you can't, there will be an ambiguity when calling the function with a single parameter.

And if you need to do this, it's a code smell.




回答3:


Why not?

class A{
public:

    void foo(int x=10, int y=10)
    {
        cout << "foo with two\n";
    }

};




回答4:


I do NOT recommend this but you CAN define such ambiguous methods and use them through different interfaces. (The following works at least with gcc 4.8.0 using -std=c++11.)

Consider two interfaces:

class IInterface1
{
public:
   virtual void funky(int i) = 0;
   virtual void funky(int i, int j) = 0;
};

class IInterface2
{
public:
   virtual void funky(int i, int j = 0) = 0;
};

IInterface1 has funky method overloaded twice for different arguments i.e. same method name but one takes single int while another takes two ints. Note in interface implementation, funky method will need to have two implementations (one for one argument and another for two arguments).

IInterface2 has single funky method that takes either one or two ints when invoked. If not provided explicitly, the second int is defaulted. Note in interface implementation, funky method will need to have only one implementation (and it always takes two arguments regardless of whether one or two were provided during invocation).

Class that implements both interfaces:

class Foo : public IInterface1, public IInterface2
{
public:
   void funky(int i) override
      { printf("  funky(int i) -> funky(%d)\n", i); }
   void funky(int i, int j = 0) override
      { printf("  funky(int i, int j = 0) -> funky(%d, %d)\n", i, j); }
   void funky(int i, int j = 0, int k = 0)
      { printf("  funky(int i, int j = 0, int k = 0) -> funky(%d, %d, %d)\n", i, j, k); }
};

For illustration, Foo also adds third overloaded version of funky method, one that takes three arguments (one mandatory and two optional).

Foo can now be used as illustrated below. Instance of Foo, master, can be used either directly, or different clients can get access to different interfaces of master object.

Foo master;
IInterface1& client1 = master;
IInterface2& client2 = master;

// AMBIGUOUS: master.funky(1); 
// AMBIGUOUS: master.funky(2,3);
puts("master.funky(4, 5, 6);");
master.funky(4, 5, 6);

puts("client1.funky(7);");
client1.funky(7);
puts("client1.funky(8, 9);");
client1.funky(8, 9);

puts("client2.funky(10);");
client2.funky(10);
puts("client2.funky(11, 12);");
client2.funky(11, 12);

This will produce the following output:

master.funky(4, 5, 6);
  funky(int i, int j = 0, int k = 0) -> funky(4, 5, 6)
client1.funky(7);
  funky(int i) -> funky(7)
client1.funky(8, 9);
  funky(int i, int j = 0) -> funky(8, 9)
client2.funky(10);
  funky(int i, int j = 0) -> funky(10, 0)
client2.funky(11, 12);
  funky(int i, int j = 0) -> funky(11, 12)

In summary, class can have apparently conflicting overloaded versions of a method. Ambiguity MUST be resolved when the method is invoked (or else the code will not compile).

PS: Again, since the above approach breaks the KISS principle, I do not condone it.




回答5:


Think about it - at compile time the compiler has to decide what one to chose. I cannot unless you supply both parameters. So the compiler has no choice but to throw its hands up and say that try again with code that does not require Mystic Meg.




回答6:


I think you can't. Because function/operator overloading is resolved by compiler at compile time. So overloading a function just by providing a default argument will cause ambiguity and compiler error.



来源:https://stackoverflow.com/questions/9943596/function-overloading-two-functions-only-differ-by-a-default-parameter

标签

工具导航Map