Overload pure virtual function with non pure virtual version
Clash Royale CLAN TAG#URR8PPP
up vote
7
down vote
favorite
With Base and Derived defined like this:
class Base
public:
virtual int f1(int a) const = 0;
virtual int f2(int a, int b) const return a+b;
;
class Derived : public Base
public:
int f1(int a) const return a;
;
int main()
Derived obj;
cout << obj.f1(1) << endl;
cout << obj.f2(1, 2) << endl;
The result is
1
3
obj.f1(1) uses the f1 implementation from Derived and obj.f2(1, 2) uses the implementation inherited from Base, which is what I want.
Now, I would like these two functions to have the same name, f, so the base class provides an implementation when there are two parameters and the derived class must implement the single parameter version (that's why it's pure virtual).
However, if I do this (just rename f1 and f2 to f):
class Base
public:
virtual int f(int a) const = 0;
virtual int f(int a, int b) const return a + b;
;
class Derived : public Base
public:
int f(int a) const return a;
;
int main()
Derived obj;
cout << obj.f(1) << endl;
cout << obj.f(1, 2) << endl;
I get the following error:
20:23: error: no matching function for call to 'Derived::f(int, int)'
20:23: note: candidate is:
14:13: note: virtual int Derived::f(int) const
14:13: note: candidate expects 1 argument, 2 provided
Why is this? Is it not possible to do this kind of overloading?
c++
add a comment |Â
up vote
7
down vote
favorite
With Base and Derived defined like this:
class Base
public:
virtual int f1(int a) const = 0;
virtual int f2(int a, int b) const return a+b;
;
class Derived : public Base
public:
int f1(int a) const return a;
;
int main()
Derived obj;
cout << obj.f1(1) << endl;
cout << obj.f2(1, 2) << endl;
The result is
1
3
obj.f1(1) uses the f1 implementation from Derived and obj.f2(1, 2) uses the implementation inherited from Base, which is what I want.
Now, I would like these two functions to have the same name, f, so the base class provides an implementation when there are two parameters and the derived class must implement the single parameter version (that's why it's pure virtual).
However, if I do this (just rename f1 and f2 to f):
class Base
public:
virtual int f(int a) const = 0;
virtual int f(int a, int b) const return a + b;
;
class Derived : public Base
public:
int f(int a) const return a;
;
int main()
Derived obj;
cout << obj.f(1) << endl;
cout << obj.f(1, 2) << endl;
I get the following error:
20:23: error: no matching function for call to 'Derived::f(int, int)'
20:23: note: candidate is:
14:13: note: virtual int Derived::f(int) const
14:13: note: candidate expects 1 argument, 2 provided
Why is this? Is it not possible to do this kind of overloading?
c++
add a comment |Â
up vote
7
down vote
favorite
up vote
7
down vote
favorite
With Base and Derived defined like this:
class Base
public:
virtual int f1(int a) const = 0;
virtual int f2(int a, int b) const return a+b;
;
class Derived : public Base
public:
int f1(int a) const return a;
;
int main()
Derived obj;
cout << obj.f1(1) << endl;
cout << obj.f2(1, 2) << endl;
The result is
1
3
obj.f1(1) uses the f1 implementation from Derived and obj.f2(1, 2) uses the implementation inherited from Base, which is what I want.
Now, I would like these two functions to have the same name, f, so the base class provides an implementation when there are two parameters and the derived class must implement the single parameter version (that's why it's pure virtual).
However, if I do this (just rename f1 and f2 to f):
class Base
public:
virtual int f(int a) const = 0;
virtual int f(int a, int b) const return a + b;
;
class Derived : public Base
public:
int f(int a) const return a;
;
int main()
Derived obj;
cout << obj.f(1) << endl;
cout << obj.f(1, 2) << endl;
I get the following error:
20:23: error: no matching function for call to 'Derived::f(int, int)'
20:23: note: candidate is:
14:13: note: virtual int Derived::f(int) const
14:13: note: candidate expects 1 argument, 2 provided
Why is this? Is it not possible to do this kind of overloading?
c++
With Base and Derived defined like this:
class Base
public:
virtual int f1(int a) const = 0;
virtual int f2(int a, int b) const return a+b;
;
class Derived : public Base
public:
int f1(int a) const return a;
;
int main()
Derived obj;
cout << obj.f1(1) << endl;
cout << obj.f2(1, 2) << endl;
The result is
1
3
obj.f1(1) uses the f1 implementation from Derived and obj.f2(1, 2) uses the implementation inherited from Base, which is what I want.
Now, I would like these two functions to have the same name, f, so the base class provides an implementation when there are two parameters and the derived class must implement the single parameter version (that's why it's pure virtual).
However, if I do this (just rename f1 and f2 to f):
class Base
public:
virtual int f(int a) const = 0;
virtual int f(int a, int b) const return a + b;
;
class Derived : public Base
public:
int f(int a) const return a;
;
int main()
Derived obj;
cout << obj.f(1) << endl;
cout << obj.f(1, 2) << endl;
I get the following error:
20:23: error: no matching function for call to 'Derived::f(int, int)'
20:23: note: candidate is:
14:13: note: virtual int Derived::f(int) const
14:13: note: candidate expects 1 argument, 2 provided
Why is this? Is it not possible to do this kind of overloading?
c++
c++
asked 46 mins ago


Milo
1,031926
1,031926
add a comment |Â
add a comment |Â
5 Answers
5
active
oldest
votes
up vote
7
down vote
You need to write
class Derived : public Base
public:
using Base::f;
int f(int a) const return a;
;
Note the using
statement. That brings the base class version back into scope.
add a comment |Â
up vote
3
down vote
Go to the concise answer by @Bathsheba to see the proper way at solving the issue -- I'm just putting this here to answer the question:
Why is this? Is it not possible to do this kind of overloading?
No, not possible as written in the original question due to [basic.scope.hiding¶3]:
In a member function definition, the declaration of a name at block
scope hides the declaration of a member of the class with the same
name; see [basic.scope.class]. The declaration of a member in a
derived class hides the declaration of a member of a base class of the
same name; see [class.member.lookup].
This clause is about names, not overloads. As such, it doesn't matter if there are other overloads in the base class, they all share the same name, which is hidden according to quote above.
add a comment |Â
up vote
1
down vote
You can either pull all definitions of Base into scope with by writing using Base::f;
or you can explcitily write for some versions of f something like this: int f(int a, int b) const override return Base::f(a,b);
class Derived : public Base
public:
int f(int a) const return a;
int f(int a, int b) const override return Base::f(a,b);
;
The version with using is already mentioned in this answer:
class Derived : public Base
public:
using Base::f;
int f(int a) const return a;
;
Note: I know that the second version does not work on MSVC 2010. I am also aware this compiler is ancient, but just for people who care ;)
add a comment |Â
up vote
0
down vote
In addition to the other solutions, if you don't want to redefine f
you could explicitly invoke f
of the base class using
int main()
Derived obj;
cout << obj.f1(1) << endl;
cout << obj.Base::f2(1, 2) << endl;
add a comment |Â
up vote
0
down vote
Why is this?
Calling one of multiple overloads of a member function is resolved by the compiler during "overload resolution". But before available overloads can be evaluated with respect to how well they match the invocation, they must be collected. This step is the "name lookup". Here,
cout << obj.f(1, 2) << endl;
the static type of the instance obj
, which is Derived
, is searched for a function signature with the name f
. There is exactly one, because once any f
has been overridden, this is the only interface Derived
offers its clients. Those from Base
are not automatically brought in - but why this limitation?
Think of an overload set as a bundled entity of a class interface. Base
offers an overload set Base::f
, and Derived
offers Derived::f
. Again, once one single function of the former overrides one function of the latter, the whole overload set is overridden (unless enriched by using Base::f
). This makes sense, because f
(the overload set) is the means a class designer gives client code to use its class.
add a comment |Â
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
7
down vote
You need to write
class Derived : public Base
public:
using Base::f;
int f(int a) const return a;
;
Note the using
statement. That brings the base class version back into scope.
add a comment |Â
up vote
7
down vote
You need to write
class Derived : public Base
public:
using Base::f;
int f(int a) const return a;
;
Note the using
statement. That brings the base class version back into scope.
add a comment |Â
up vote
7
down vote
up vote
7
down vote
You need to write
class Derived : public Base
public:
using Base::f;
int f(int a) const return a;
;
Note the using
statement. That brings the base class version back into scope.
You need to write
class Derived : public Base
public:
using Base::f;
int f(int a) const return a;
;
Note the using
statement. That brings the base class version back into scope.
answered 45 mins ago


Bathsheba
167k26237352
167k26237352
add a comment |Â
add a comment |Â
up vote
3
down vote
Go to the concise answer by @Bathsheba to see the proper way at solving the issue -- I'm just putting this here to answer the question:
Why is this? Is it not possible to do this kind of overloading?
No, not possible as written in the original question due to [basic.scope.hiding¶3]:
In a member function definition, the declaration of a name at block
scope hides the declaration of a member of the class with the same
name; see [basic.scope.class]. The declaration of a member in a
derived class hides the declaration of a member of a base class of the
same name; see [class.member.lookup].
This clause is about names, not overloads. As such, it doesn't matter if there are other overloads in the base class, they all share the same name, which is hidden according to quote above.
add a comment |Â
up vote
3
down vote
Go to the concise answer by @Bathsheba to see the proper way at solving the issue -- I'm just putting this here to answer the question:
Why is this? Is it not possible to do this kind of overloading?
No, not possible as written in the original question due to [basic.scope.hiding¶3]:
In a member function definition, the declaration of a name at block
scope hides the declaration of a member of the class with the same
name; see [basic.scope.class]. The declaration of a member in a
derived class hides the declaration of a member of a base class of the
same name; see [class.member.lookup].
This clause is about names, not overloads. As such, it doesn't matter if there are other overloads in the base class, they all share the same name, which is hidden according to quote above.
add a comment |Â
up vote
3
down vote
up vote
3
down vote
Go to the concise answer by @Bathsheba to see the proper way at solving the issue -- I'm just putting this here to answer the question:
Why is this? Is it not possible to do this kind of overloading?
No, not possible as written in the original question due to [basic.scope.hiding¶3]:
In a member function definition, the declaration of a name at block
scope hides the declaration of a member of the class with the same
name; see [basic.scope.class]. The declaration of a member in a
derived class hides the declaration of a member of a base class of the
same name; see [class.member.lookup].
This clause is about names, not overloads. As such, it doesn't matter if there are other overloads in the base class, they all share the same name, which is hidden according to quote above.
Go to the concise answer by @Bathsheba to see the proper way at solving the issue -- I'm just putting this here to answer the question:
Why is this? Is it not possible to do this kind of overloading?
No, not possible as written in the original question due to [basic.scope.hiding¶3]:
In a member function definition, the declaration of a name at block
scope hides the declaration of a member of the class with the same
name; see [basic.scope.class]. The declaration of a member in a
derived class hides the declaration of a member of a base class of the
same name; see [class.member.lookup].
This clause is about names, not overloads. As such, it doesn't matter if there are other overloads in the base class, they all share the same name, which is hidden according to quote above.
edited 12 mins ago
StoryTeller
82.9k12166230
82.9k12166230
answered 18 mins ago
SkepticalEmpiricist
3,473720
3,473720
add a comment |Â
add a comment |Â
up vote
1
down vote
You can either pull all definitions of Base into scope with by writing using Base::f;
or you can explcitily write for some versions of f something like this: int f(int a, int b) const override return Base::f(a,b);
class Derived : public Base
public:
int f(int a) const return a;
int f(int a, int b) const override return Base::f(a,b);
;
The version with using is already mentioned in this answer:
class Derived : public Base
public:
using Base::f;
int f(int a) const return a;
;
Note: I know that the second version does not work on MSVC 2010. I am also aware this compiler is ancient, but just for people who care ;)
add a comment |Â
up vote
1
down vote
You can either pull all definitions of Base into scope with by writing using Base::f;
or you can explcitily write for some versions of f something like this: int f(int a, int b) const override return Base::f(a,b);
class Derived : public Base
public:
int f(int a) const return a;
int f(int a, int b) const override return Base::f(a,b);
;
The version with using is already mentioned in this answer:
class Derived : public Base
public:
using Base::f;
int f(int a) const return a;
;
Note: I know that the second version does not work on MSVC 2010. I am also aware this compiler is ancient, but just for people who care ;)
add a comment |Â
up vote
1
down vote
up vote
1
down vote
You can either pull all definitions of Base into scope with by writing using Base::f;
or you can explcitily write for some versions of f something like this: int f(int a, int b) const override return Base::f(a,b);
class Derived : public Base
public:
int f(int a) const return a;
int f(int a, int b) const override return Base::f(a,b);
;
The version with using is already mentioned in this answer:
class Derived : public Base
public:
using Base::f;
int f(int a) const return a;
;
Note: I know that the second version does not work on MSVC 2010. I am also aware this compiler is ancient, but just for people who care ;)
You can either pull all definitions of Base into scope with by writing using Base::f;
or you can explcitily write for some versions of f something like this: int f(int a, int b) const override return Base::f(a,b);
class Derived : public Base
public:
int f(int a) const return a;
int f(int a, int b) const override return Base::f(a,b);
;
The version with using is already mentioned in this answer:
class Derived : public Base
public:
using Base::f;
int f(int a) const return a;
;
Note: I know that the second version does not work on MSVC 2010. I am also aware this compiler is ancient, but just for people who care ;)
edited 31 mins ago
answered 38 mins ago
P i
2,340832
2,340832
add a comment |Â
add a comment |Â
up vote
0
down vote
In addition to the other solutions, if you don't want to redefine f
you could explicitly invoke f
of the base class using
int main()
Derived obj;
cout << obj.f1(1) << endl;
cout << obj.Base::f2(1, 2) << endl;
add a comment |Â
up vote
0
down vote
In addition to the other solutions, if you don't want to redefine f
you could explicitly invoke f
of the base class using
int main()
Derived obj;
cout << obj.f1(1) << endl;
cout << obj.Base::f2(1, 2) << endl;
add a comment |Â
up vote
0
down vote
up vote
0
down vote
In addition to the other solutions, if you don't want to redefine f
you could explicitly invoke f
of the base class using
int main()
Derived obj;
cout << obj.f1(1) << endl;
cout << obj.Base::f2(1, 2) << endl;
In addition to the other solutions, if you don't want to redefine f
you could explicitly invoke f
of the base class using
int main()
Derived obj;
cout << obj.f1(1) << endl;
cout << obj.Base::f2(1, 2) << endl;
answered 2 mins ago
dan
1462
1462
add a comment |Â
add a comment |Â
up vote
0
down vote
Why is this?
Calling one of multiple overloads of a member function is resolved by the compiler during "overload resolution". But before available overloads can be evaluated with respect to how well they match the invocation, they must be collected. This step is the "name lookup". Here,
cout << obj.f(1, 2) << endl;
the static type of the instance obj
, which is Derived
, is searched for a function signature with the name f
. There is exactly one, because once any f
has been overridden, this is the only interface Derived
offers its clients. Those from Base
are not automatically brought in - but why this limitation?
Think of an overload set as a bundled entity of a class interface. Base
offers an overload set Base::f
, and Derived
offers Derived::f
. Again, once one single function of the former overrides one function of the latter, the whole overload set is overridden (unless enriched by using Base::f
). This makes sense, because f
(the overload set) is the means a class designer gives client code to use its class.
add a comment |Â
up vote
0
down vote
Why is this?
Calling one of multiple overloads of a member function is resolved by the compiler during "overload resolution". But before available overloads can be evaluated with respect to how well they match the invocation, they must be collected. This step is the "name lookup". Here,
cout << obj.f(1, 2) << endl;
the static type of the instance obj
, which is Derived
, is searched for a function signature with the name f
. There is exactly one, because once any f
has been overridden, this is the only interface Derived
offers its clients. Those from Base
are not automatically brought in - but why this limitation?
Think of an overload set as a bundled entity of a class interface. Base
offers an overload set Base::f
, and Derived
offers Derived::f
. Again, once one single function of the former overrides one function of the latter, the whole overload set is overridden (unless enriched by using Base::f
). This makes sense, because f
(the overload set) is the means a class designer gives client code to use its class.
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Why is this?
Calling one of multiple overloads of a member function is resolved by the compiler during "overload resolution". But before available overloads can be evaluated with respect to how well they match the invocation, they must be collected. This step is the "name lookup". Here,
cout << obj.f(1, 2) << endl;
the static type of the instance obj
, which is Derived
, is searched for a function signature with the name f
. There is exactly one, because once any f
has been overridden, this is the only interface Derived
offers its clients. Those from Base
are not automatically brought in - but why this limitation?
Think of an overload set as a bundled entity of a class interface. Base
offers an overload set Base::f
, and Derived
offers Derived::f
. Again, once one single function of the former overrides one function of the latter, the whole overload set is overridden (unless enriched by using Base::f
). This makes sense, because f
(the overload set) is the means a class designer gives client code to use its class.
Why is this?
Calling one of multiple overloads of a member function is resolved by the compiler during "overload resolution". But before available overloads can be evaluated with respect to how well they match the invocation, they must be collected. This step is the "name lookup". Here,
cout << obj.f(1, 2) << endl;
the static type of the instance obj
, which is Derived
, is searched for a function signature with the name f
. There is exactly one, because once any f
has been overridden, this is the only interface Derived
offers its clients. Those from Base
are not automatically brought in - but why this limitation?
Think of an overload set as a bundled entity of a class interface. Base
offers an overload set Base::f
, and Derived
offers Derived::f
. Again, once one single function of the former overrides one function of the latter, the whole overload set is overridden (unless enriched by using Base::f
). This makes sense, because f
(the overload set) is the means a class designer gives client code to use its class.
edited 1 min ago
answered 21 mins ago


lubgr
6,59021340
6,59021340
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52364745%2foverload-pure-virtual-function-with-non-pure-virtual-version%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password