Re: function template explicit specialization not chosen
Am 19.04.2012 20:53, schrieb Meng Zhu:
So even though the argument type A is a cv-qualified type (The type
is 'dummy const'), this is irrelevant here. As a rule of thumb one
should remember that a function template that looks like using
"by-value" arguments, will have this way, unless you provide
explicit template parameters that would change that.
May I also ask that b's type is dummy const& and in hash(b) you
directly started talking about A being dummy const (taking off the
reference already), this stripe off of reference for the expression
is supported by 5/5 [expr]
"If an expression initially has the type ?reference to T? (8.3.2,
8.5.3), the type is adjusted to T prior to any further analysis. The
expression designates the object or function denoted by the
reference, and the expression is an lvalue or an xvalue, depending
on the expression."
Exactly. The declared type of b is irrelevant in the context of
expression analysis. The expression 'b' has type 'const dummy' and
belongs to the value category 'lvalue'.
Given this rule in 5/5. It is also impossible for decltype(b) to be
dummy const& were decltype designed to use the template argument
deduction rules, and that's why in 7.1.6.2/4 [dcl.type.simple],
decltype is given a set of special rule to follow.
Unless I'm misunderstanding you here, your description of decltype(b)
is either incorrect or misleading, therefore let me clarify: The
result of decltype(b) will be 'const dummy&'. You are correct, that
this requires extra wording for the specification of decltype. We have
bullet 1 here and note that the wording says:
"decltype(e) is the type of the entity named by e"
It does *not* speak of the "type of the expression e", because that
would be 'const dummy' again. The "entity named by e" is the
lvalue-reference variable 'b'.
Moreover, since auto follows template deduction rules, it means the
following is true.
auto c = b; // c is of type dummy
Correct, the deduction rule of auto is equal to the deduction result
from
template <class U> void f(U u);
here. Note that this is similar to your example.
decltype(b) d = b; // d is of type dummy const&
Am I right in the claims? Thanks again.
Correct, decltype(b) evaluates to 'const dummy&', because that is the
type of the entity named by 'b'.
There won't happen any overload resolution between 'int
hash(dummy)' and 'int hash(const dummy&). There does only exist a
single function template, the compiler deduces the parameter types
by the process described in [temp.deduct.call] and this ends in a
deduced form of int hash<dummy>(dummy). There does not exist an
explicit specialization of that form, therefore the primary form is
instantiated. This clearly demonstrates that you would need to
provide a specialization of this form
template<> int hash (dummy) { return 0; }
to get the compiler find the wanted specialization.
Now that I see the process, I understand only the dummy
specialization exists.
I cannot really agree about the usage of 'exists' in this context,
therefore let me rephrase to be sure that we are on the same line:
It doesn't matter how many explicit specializations had been provided.
It is only imported *which* specialization the compiler will deduce.
This will be 'int hash<dummy>(dummy)' in this example, irrespective
whether this is the result of instantiating the primary template or
whether this was an explicit specialization. The specialization 'int
hash<const dummy&>(const dummy&)' will not be selected.
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]