According to some quotes in standard:
[over.match.funcs]/4
[...] For non-conversion functions introduced by a using-declaration into a derived class, the function is considered to be a member of the derived class for the purpose of defining the type of the implicit object parameter.
And consider the following code:
#include <iostream>
struct Base {
void show(double) {
std::cout << "0" << std::endl;
}
};
struct Test :Base {
using Base::show; //#1
void show(double) { //#2
std::cout << "1" << std::endl;
}
};
int main() {
Test t;
t.show(1.2);
}
According to the standard I cited,it means that take a implict object parameter of type Test
as that of #1
.
For #1
,the declaration would be show(Test&,double)
.
For #2
,the declaration would be show(Test&,double)
.
so in the purpose of overload resolution,the each implicit conversion sequence of #1
is indistinguishable with that of #2
,the invocation of t.show(1.2)
would be ambiguous,however #2
is called,why? if I miss something in the standard,please correct me.
Test::show(double)
has the same signature with the Base::show(double)
; it just hides the one from the base class.
For using declaration,
(emphasis mine)
If the derived class already has a member with the same name, parameter list, and qualifications, the derived class member hides or overrides (doesn't conflict with) the member that is introduced from the base class.
From the standard, [namespace.udecl]/14
When a using-declarator brings declarations from a base class into a derived class, member functions and member function templates in the derived class override and/or hide member functions and member function templates with the same name, parameter-type-list ([dcl.fct]), trailing requires-clause (if any), cv-qualification, and ref-qualifier (if any), in a base class (rather than conflicting). Such hidden or overridden declarations are excluded from the set of declarations introduced by the using-declarator. [ Example:
struct B { virtual void f(int); virtual void f(char); void g(int); void h(int); }; struct D : B { using B::f; void f(int); // OK: D::f(int) overrides B::f(int); using B::g; void g(char); // OK using B::h; void h(int); // OK: D::h(int) hides B::h(int) }; ...