class A
{
struct B{};
public:
static void test(A::B){}
};
struct C
{
template<class T>
operator T()
{
return T();
}
};
int main()
{
A::test(C());
}
This code works for clang 3.7, gcc 5.1 and vc++ 14.2.
2 problems,
1. Why can template deduce the type is A::B? (so smart!)
As far as I know, template deduce the type by return statement instead of parameter.
But I found something interested in N4606 12.3.2 6 A conversion function template shall not have a deduced return type (7.1.7.4).
(However, I cannot find further information about this, because 7.1.7.4 is too hard to understand.)
2. Why could conversion function template access A::B?
Thanks.
- Why can template deduce the type is A::B? (so smart!)
Since test()
takes an A::B
, you need a way to convert a C
to an A::B
. We can attempt an initialization by conversion function, for which we have in [over.match.conv]:
The conversion functions of
S
and its base classes are considered. Those non-explicit conversion functions that are not hidden withinS
and yield typeT
or a type that can be converted to typeT
via a standard conversion sequence (13.3.3.1.1) are candidate functions.
We perform template deduction according to [temp.conv]:
Template argument deduction is done by comparing the return type of the conversion function template (call it P) with the type that is required as the result of the conversion (call it A; see 8.6, 13.3.1.5, and 13.3.1.6 for the determination of that type) as described in 14.8.2.5.
Basically, we deduce the T
in template <class T> operator T()
to be A::B
. This is a well-formed conversion sequence, and the only viable one, so that's what happens.
The line you quote, about "deduced return type", refers to auto
or decltype
in the return type. This doesn't happen here.
- Why could conversion function template access A::B?
Access rules are strictly about names. The name B
, and only the name, is private to A
. But we're not accessing the name, we're deducing the type directly.
B
's constructor is public, so the body of the conversion function is also well-formed, so everything about the code is well-formed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With