Templated conversion function to function pointer - c++

Yay, another question title composed of a random sequence of C++ terms!
Usually we make a class Callable by implementing operator(). But you can also do so by implementing a user-defined conversion to function pointer or reference type. Instead of using perfect forwarding, a conversion function can return a pointer to a function which is then called with the original argument list.
struct call_printf {
typedef int printf_t( char const *, ... );
operator printf_t & () { return std::printf; }
};
http://ideone.com/kqrJz
As far as I can tell, the typedef above is a syntactic necessity. The name of a conversion function is formed from a type-specifier-seq, which does not allow a construct like int (*)(). That would require an abstract-declarator. Presumably the reason is that such type names get complicated, and complex constructs used as object names are tough to parse.
Conversion functions are also allowed to be templated, but the template arguments must be deduced, because there is nowhere to explicitly specify them. (That would defeat the whole point of implicit conversion.)
Question #1: In C++03, is there was no way to specify a function conversion operator template? It appears there was no way to resolve the template arguments (i.e., name them in a deduced context) in an acceptable function pointer type.
Here is the equivalent reference from C++11, §13.3.1.1.2/2 [over.call.object]. It's substantially the same from C++03:
In addition, for each non-explicit conversion function declared in T of the form
operator conversion-type-id () cv-qualifier attribute-specifier-seqopt;
where cv-qualifier is the same cv-qualification as, or a greater cv-qualification than, cv, and where conversion-type-id denotes the type “pointer to function of (P1,...,Pn) returning R”, or the type “reference to pointer to function of (P1,...,Pn) returning R”, or the type “reference to function of (P1,...,Pn) returning R”, a surrogate call function with the unique name call-function and having the form
R call-function ( conversion-type-id F, P1 a1, ... ,Pn an) { return F (a1,... ,an); }
is also considered as a candidate function. Similarly, surrogate call functions are added to the set of candidate functions for each non-explicit conversion function declared in a base class of T provided the
function is not hidden within T by another intervening declaration.
Question #2: In C++11, can such a conversion be specified using a default template argument? This is useful for SFINAE. The only difference here from the above example is that the conversion-type-id only represents a function reference after instantiation, because it's a dependent type (despite invariance). This trips up GCC and it skips the member template.
enum { call_alternate = true; }
struct call_switch {
template< bool en = call_alternate >
operator typename std::enable_if< en, decltype( fn_1 ) & >::type ()
{ return fn_1; }
template< bool en = ! call_alternate >
operator typename std::enable_if< en, decltype( fn_2 ) & >::type ()
{ return fn_2; }
};
We also have alias templates. It seems that alias substitution occurs before instantiation, given the example in §14.5.7/2, where the declarations of process conflict. In GCC 4.7, this code at least instantiates the declaration, but then it produces a bizarre "candidate expects 2 arguments, 2 provided" error.
template< typename t >
using fn_t = void (&)( t );
struct talk {
template< typename t >
operator fn_t< t >() { return fn; }
};
int main() {
talk()( 3 );
}

Question #1: In C++03, is there was no way to specify a function conversion operator template? It appears there was no way to resolve the template arguments (i.e., name them in a deduced context) in an acceptable function pointer type.
Yes, that is correct.
Question #2: In C++11, can such a conversion be specified using a default template argument?
It can, and you can also use alias templates, but you cannot use such a conversion function template for creating surrogate call functions. You can use it for converting your class object to function pointers in implicit conversions otherwise.
We also have alias templates. It seems that alias substitution occurs before instantiation, given the example in §14.5.7/2, where the declarations of process conflict. In GCC 4.7, this code at least instantiates the declaration, but then it produces a bizarre "candidate expects 2 arguments, 2 provided" error.
Yes, this is https://groups.google.com/forum/?fromgroups#!topic/comp.std.c++/lXLFBcF_m3c (and caused closure of DR395), but even though such a conversion function template can work in cases like void(&p)() = yourClassObject, it won't work for surrogate call functions, because there the conversion function needs to provide a fixed non-dependent type that the class object is converted to when the surrogate function is called, but a conversion function template does not provide such a type normally (weird things like template<typename = int> operator Identity<void(*)()>(); aside...).
I think that GCC may incorrectly generates the candidate call-function(void (&)( t ), t) with the dependent types still there and try to call that candidate, thereby violating some invariant of it (which could explain the weird error message - possibly hitting an } else { ... } unexpectedly somewhere).

Related

Why does typeid refuse to work for function types with const at the end?

So I've got this code:
template <typename T, typename class_t>
struct remove_ptr_to_member { using type = T; };
template <typename T, typename class_t>
struct remove_ptr_to_member<T class_t::*, class_t> { using type = T; };
class container {
public:
void func() const;
};
void print_member_type() {
std::cout << typeid(typename remove_ptr_to_member<decltype(&container::func), container>::type).name() << '\n';
}
I get this error message when trying to compile it:
error: non-member function of type 'typename remove_ptr_to_member<decltype(&container::func), container>::type' (aka 'void () const') cannot have 'const' qualifier
As I understand it, the const at the end of the function is part of it's type. Is typeid not accepting it because it's an invalid type (since non-member functions can't have const at the end)? Why is it that I can create a type that shouldn't actually exist? How would I go about removing the const, so as to make everything compile properly?
A function type with const or other cvref-qualifiers is a valid type in the language, but it has very limited uses, mainly to declare non-static member functions and to form pointers to non-static member functions.
Therefore the standard has restrictions on where they may be used, listed in [dcl.fct]/6. In particular this list does not include the operand of typeid. As a consequence you are not allowed to use such a function type as operand of typeid.
This was also subject of an editorial issue which resulted in a note being added to the description of typeid in the standard to make it clear that this is not permitted.
So, although there is nothing wrong with how you obtain the function type, you can't use it as typeid operand.
Unfortunately I don't think there is any type trait in std:: that allows you to remove the cvref qualifiers from the function type.
These can be implemented by yourself, but implementing such traits on qualified function types is notoriously tedious because there are (if I didn't miscount) 24 overloads or partial specializations for all possible combinations of cvref and noexcept qualifiers required. (Actually 48 to include variadic functions.)
See for example this older question about it. However note that this question is pre-C++17. Since C++17 function types with and without noexcept need to also be differentiated.
Instead you might want to have a look at Boost.CallableTraits which has a list of remove_* type traits which you can use to remove the const/volatile/&/&&-qualifiers.

convert member function to pointer to member function

Clang,GCC,MSVC have different opinion about conversion of member functions.
Who is right ?
https://gcc.godbolt.org/z/QNsgwd
template<typename T>
struct a
{
template <typename... Args>
void va(Args...) {}
template <typename X>
void x(X) {}
void y(int) {}
};
struct b : a<b>
{
void testva()
{
using F = void (a<b>::*)();
F f = (F)&a<b>::va<int>; // gcc: error, msvc: error, clang: ok
}
void testx()
{
using F = void (a<b>::*)();
F f = (F)&a<b>::x<int>;// gcc: error, msvc: ok, clang: ok
}
void testy()
{
using F = void (a<b>::*)();
F f = (F)& a<b>::y; // gcc: ok, msvc: ok, clang: ok
}
};
testx and testy are well-formed, so gcc is wrong about testx. But the Standard is somewhat vague about testva.
Starting with the easiest, in testy the expression &a<b>::y names a non-template function which is not overloaded, so it has type void (a<b>::*)(int) without need for further analysis. Conversion from any pointer-to-member-function to any other pointer-to-member-function is a well-formed reinterpret_cast with unspecified results except if converted back to the original type, and a C-style cast can do what a reinterpret_cast can do.
For template functions we have [over.over]/1-2:
A use of an overloaded function name without arguments is resolved in certain contexts to a function, a pointer to function or a pointer to member function for a specific function from the overload set. A function template name is considered to name a set of overloaded functions in such contexts. A function with type F is selected for the function type FT of the target type required in the context if F (after possibly applying the function pointer conversion) is identical to FT. The target can be
...
an explicit type conversion ([expr.type.conv], [expr.static.cast], [expr.cast]),
...
If the name is a function template, template argument deduction is done ([temp.deduct.funcaddr]), and if the argument deduction succeeds, the resulting template argument list is used to generate a single function template specialization, which is added to the set of overloaded functions considered. [ Note: As described in [temp.arg.explicit], if deduction fails and the function template name is followed by an explicit template argument list, the template-id is then examined to see whether it identifies a single function template specialization. If it does, the template-id is considered to be an lvalue for that function template specialization. The target type is not used in that determination. — end note ]
So this means we first try template argument deduction for a<b>::x<int>, matching it to the target type void (a<b>::*)(). But there are no specializations that can possibly give an exact match, since they all have one argument, not zero, so deduction fails. But per the note, there's also [temp.arg.explicit] (paragraph 3 in C++17, 4 in the latest C++20 draft):
Trailing template arguments that can be deduced or obtained from default template-arguments may be omitted from the list of explicit template-arguments. A trailing template parameter pack ([temp.variadic]) not otherwise deduced will be deduced as an empty sequence of template arguments. ... In contexts where deduction is done and fails, or in contexts where deduction is not done, if a template argument list is specified and it, along with any default template arguments, identifies a single function template specialization, then the template-id is an lvalue for the function template specialization.
In testx, the template-id a<b>::x<int> identifies a single function template specialization. So it names that specialization, and again the C-style cast is valid with unspecified result.
So in testva, does a<b>::va<int> identify a single specialization? It would certainly be possible to use that expression to name different specializations, via [temp.arg.explicit]/9:
Template argument deduction can extend the sequence of template arguments corresponding to a template parameter pack, even when the sequence contains explicitly specified template arguments.
Except this says "template argument deduction". And here the template argument deduction involved fails, since it required an impossible match with the target type void (a<b>::*)(). So nothing really explains whether a<b>::va<int> identifies a single specialization, since no other method of getting additional template arguments is described, or identifies multiple specializations, since it could be validly used in other contexts with matching target types.
clang is right
[expr.reinterpret.cast]/10
A prvalue of type “pointer to member of X of type T1” can be explicitly converted to a prvalue of a different type “pointer to member of Y of type T2” if T1 and T2 are both function types or both object types. The null member pointer value is converted to the null member pointer value of the destination type. The result of this conversion is unspecified, except in the following cases:
Converting a prvalue of type “pointer to member function” to a different pointer-to-member-function type and back to its original type yields the original pointer-to-member value.
Converting a prvalue of type “pointer to data member of X of type T1” to the type “pointer to data member of Y of type T2” (where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer-to-member value.
&a<b>::va<int> et al. are prvalue of type "pointer to member of a<b> of type void(int)" and converting it (without calling the resulting function pointer whose value is unspecified) is legal.
Let's simplify to this example:
struct a {
template <typename... Args>
void va(Args...) {}
template <typename X>
void x(X) {}
void y(int) {}
};
using no_args = void(a::*)();
using int_arg = void(a::*)(int);
And lets try the following four things:
reinterpret_cast<no_args>(&MEMBER_FUNCTION); // (1)
(no_args) &MEMBER_FUNCTION; // (2)
(no_args) static_cast<int_arg>(&MEMBER_FUNCTION); // (3)
int_arg temp = &MEMBER_FUNCTION; (no_args) temp; // (4)
(Replacing MEMBER_FUNCTION with &a::va<int>, &a::x<int> and &a::y).
clang compiles all of them.
gcc compiles everything except (2) with &a::va<int> and &a::x<int>.
MSVC compiles everything except (1) and (2) with &a::va<int> (but is fine with &a::x<int>).
Notice that (3) is essentially the same as (4).
https://gcc.godbolt.org/z/a2qqyo showing an example of this.
What you can see from this is that &MEMBER_FUNCTION is not resolved to a specific member function pointer in case of templates, but if it is resolved, it is allowed to reinterpret it into another member function pointer type.
What the standard has to say:
[over.over]/1:
A use of an overloaded function name without arguments is resolved in certain contexts to a function, a pointer to function or a pointer to member function for a specific function from the overload set.
A function template name is considered to name a set of overloaded functions in such contexts.
A function with type F is selected for the function type FT of the target type required in the context if F (after possibly applying the function pointer conversion) is identical to FT.
[ Note: That is, the class of which the function is a member is ignored when matching a pointer-to-member-function type.
— end note
 ]
The target can be:
[...]
- an explicit type conversion ([expr.type.conv], [expr.static.cast], [expr.cast])
An example given later on is:
int f(double);
int f(int);
void g() {
(int (*)(int))&f; // cast expression as selector
}
And a few more quotes about templates:
[temp.deduct.funcaddr]/1:
Template arguments can be deduced from the type specified when taking the address of an overloaded function.
The function template's function type and the specified type are used as the types of P and A, and the deduction is done as described in [temp.deduct.type].
[temp.arg.explicit]/4
[...] if a template argument list is specified and it, along with any default template arguments, identifies a single function template specialization, then the template-id is an lvalue for the function template specialization.
This seems like MSVC is right.
&a::va<int> is not resolved unless you assign/cast it to a void(a::*)(int). You should also be able to assign it to void(a::*)(int, char) or void(a::*)(int, double, char), where the Args would be deduced as { int, char } and { int, double, char } respectively. That means that (no_args) &a::va<int> should fail, as there are many possible sets of Args it could be (All of them start with int, and clang overzealously resolves it), and none of them take zero parameters, so (no_args) &a::va<int> is a static_cast that should fail.
As for &a::x<int>, there is only one possible function, so it should work exactly the same way as &a::y (But gcc still hasn't resolved it yet).

Does sizeof operator cause templates argument deduction to occur?

I know that sizeof operator doesn't evaluate its expression argument to get the answer. But it is not one of the non-deducted contexts for templates. So I am wondering how it interacts with templates and specifically template argument deductions. For instance, the following is taken from C++ Templates: The Complete Guide:
template<typename T>
class IsClassT {
private:
typedef char One;
typedef struct { char a[2]; } Two;
template<typename C> static One test(int C::*);
template<typename C> static Two test(...);
public:
enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 };
enum { No = !Yes };
};
This type function determines, as its name suggests, whether a template argument is a class type. The mechanism is essentially the following condition test:
sizeof(IsClassT<T>::test<T>(0)) == 1
Note, however, the function template argument is explicit (T in this case) and the function argument is a plan 0 of type int, which is not of type pointer to an int member of class C. In normal function template argument deduction, when T is really of class type and function argument is simply a 0, deduction on static One test(int C::*); should fail since implicit conversion (0 used as null pointer type) is not allowed during template argument deduction and (I guess?) SFINAE should kick in and overload resolution would have selected
static Two test(...);
However, since the whole expression is wrapped inside the sizeof operator, it seems that passing the 0 without a cast works.
Can someone clarify:
if my understanding of function template argument deduction is correct?
if it is because of the non-evaluation nature of sizeof operator that makes passing 0 successful? And
if 0 doesn't matter in this context, we could choose any argument in place of 0, such as 0.0, 100 or even user defined types?
Conclusion: I found in C++ Primer that has a section on function template explicit arguments. And I quote "Normal Conversions Apply for Explicitly Specified Arguments" and "For the same reasons that normal conversions are permitted for parameters that
are defined using ordinary types (§ 16.2.1, p. 680), normal conversions also apply
for arguments whose template type parameter is explicitly specified". So the 0 in this question is actually implicitly converted to null pointer to members (pointer conversion).
Template Argument Deduction is done when instantiating a function. This is done as part of function overloading (and other contexts not applicable here). In TAD, the types of function arguments are used to deduce the template parameters, but not all arguments are necessarily used. This is where the "non-deduced context" comes from. If a template parameter appears in a non-deduced context within a function signature, it can't be deduced from the actual argument.
sizeof(T) is in fact a non-deduced context for T, but it's so obvious that nobody even bothered to mention it. E.g.
template< int N> class A {};
template<typename T> void f(A<sizeof(T)>);
f(A<4>());
The compiler isn't going to pick a random T that has sizeof(T)==4.
Now your example actually doesn't have a sizeof inside the argument list of a function template, so "non-deduced context" is an irrelevant consideration. That said, it's important to understand what "sizeof doesn't evaluate its expression argument" means. It means the expression value isn't calculated, but the expression type is. In your example, IsClassT<T>::test<T>(0) won't be called at runtime, but its type is determined at compile time.

can't pass function pointer to method in parent class through a variadic function--compiler bug?

Say you have two structures, Generic_A and Generic_B. Generic_B is derived from Generic_A. Why is it that when Generic_B tries to access a method in its parent, Generic_A, it generates the following error:
test2.cpp: In function 'int main()':
test2.cpp:26: error: no matching function for call to 'case1(void (Generic_A::*)()'
This code, compiled using gcc version 4.4.6, replicates the problem:
#include <stdio.h>
struct Generic_A
{
void p1() { printf("%s\n", __PRETTY_FUNCTION__); };
};
struct Generic_B : public Generic_A
{
void p2() { printf("%s\n", __PRETTY_FUNCTION__); };
};
template <class T,class... ARGS>
void case1( void (T::*p)(ARGS...) ) {
printf("%s\n", __PRETTY_FUNCTION__);
}
template <class T>
void case2( void (T::*p)() ) {
printf("%s\n", __PRETTY_FUNCTION__);
}
main()
{
//generates error
case1<Generic_B>(&Generic_B::p1);
//compiles fine
case2<Generic_B>(&Generic_B::p1);
}
The only apparent difference between the two function calls is that case1() has a template argument parameter, and case2() doesn't. Shouldn't they both allow you to pass a function pointer to a method in Generic_B's parent (ie &Generic_B::p1)?
Also, casting the function pointer in case1 seems to sometimes resolve the error:
case1<Generic_B>( (void (Generic_B::*)()) &Generic_B::p1);
What is going on?
This is tricky, but it turns out g++ is correct.
First, the type of expression &Generic_B::p1 is void (Generic_A::*)(). The compiler uses Generic_B:: to qualify its name lookup and finds the member of Generic_A. The expression type depends on the definition of the member found, not the type used within the qualified-id.
But it's also legal to have
void (Generic_B::*member)() = &Generic_B::p1;
since there is an implicit conversion from void (Generic_A::*)() to void (Generic_B::*)().
Whenever a function template is used as a function call, the compiler goes through three basic steps (or attempts to):
Substitute any explicit template arguments for the template parameters in the function declaration.
For each function parameter that still involves at least one template parameter, compare the corresponding function argument to that function parameter, to (possibly) deduce those template parameters.
Substitute the deduced template parameters into the function declaration.
In this case, we have the function template declaration
template <class T,class... ARGS>
void case1( void (T::*p)(ARGS...) );
where the template parameters are T and ARGS, and the function call expression
case1<Generic_B>(&Generic_B::p1)
where the explicit template argument is Generic_B and the function argument is &Generic_B::p1.
So step 1, substitute the explicit template argument:
void case1( void (Generic_B::*p)(ARGS...) );
Step 2, compare parameter types and argument types:
The parameter type (P in Standard section 14.8.2) is void (Generic_B::*)(ARGS...). The argument type (A) is void (Generic_A::*)().
C++ Standard (N3485) 14.8.2.1p4:
In general, the deduction process attempts to find template argument values that will make the deduced A identical to A (after the type A is transformed as described above). However, there are three cases that allow a difference:
If the original P is a reference type, the deduced A (i.e., the type referred to by the reference) can be more cv-qualified than the transformed A.
The transformed A can be another pointer or pointer to member type that can be converted to the deduced A via a qualification conversion (4.4).
If P is a class and P has the form simple-template-id, then the transformed A can be a derived class of the deduced A. Likewise, if P is a pointer to a class of the form simple-template-id, the transformed A can be a pointer to a derived class pointed to by the deduced A.
So type deduction allows for certain implicit conversions involving const / volatile and/or derived-to-base conversions, but implicit conversions of pointers to members are not considered.
In the case1 example, type deduction fails, and the function is not a match.
Unfortunately, there's no way to explicitly specify that your template parameter pack ARGS should be substituted with an empty list. As you already discovered, you can get this working by explicitly doing the necessary pointer to member function conversion yourself, even though it's otherwise valid as an implicit conversion.

Why can template instances not be deduced in `std::reference_wrapper`s?

Suppose I have some object of type T, and I want to put it into a reference wrapper:
int a = 5, b = 7;
std::reference_wrapper<int> p(a), q(b); // or "auto p = std::ref(a)"
Now I can readily say if (p < q), because the reference wrapper has a conversion to its wrapped type. All is happy, and I can process a collection of reference wrappers just like they were the original objects.
(As the question linked below shows, this can be a useful way to produce an alternate view of an existing collection, which can be rearranged at will without incurring the cost of a full copy, as well as maintaining update integrity with the original collection.)
However, with some classes this doesn't work:
std::string s1 = "hello", s2 = "world";
std::reference_wrapper<std::string> t1(s1), t2(s2);
return t1 < t2; // ERROR
My workaround is to define a predicate as in this answer*; but my question is:
Why and when can operators be applied to reference wrappers and transparently use the operators of the wrapped types? Why does it fail for std::string? What has it got to do with the fact that std::string is a template instance?
*) Update: In the light of the answers, it seems that using std::less<T>() is a general solution.
Edit: Moved my guesswork to the bottom, here comes the normative text why this won't work. TL;DR version:
No conversions allowed if the function parameter contains a deduced template parameter.
§14.8.3 [temp.over] p1
[...] When a call to that name is written (explicitly, or implicitly using the operator
notation), template argument deduction (14.8.2) and checking of any explicit template arguments (14.3) are performed for each function template to find the template argument values (if any) that can be used with that function template to instantiate a function template specialization that can be invoked with the call arguments.
§14.8.2.1 [temp.deduct.call] p4
[...] [ Note: as specified in 14.8.1, implicit conversions will be performed on a function argument to convert it to the type of the corresponding function parameter if the parameter contains no template-parameters that participate in template argument deduction. [...] —end note ]
§14.8.1 [temp.arg.explicit] p6
Implicit conversions (Clause 4) will be performed on a function argument to convert it to the type of the corresponding function parameter if the parameter type contains no template-parameters that participate in template argument deduction. [ Note: Template parameters do not participate in template argument deduction if they are explicitly specified. [...] —end note ]
Since std::basic_string depends on deduced template parameters (CharT, Traits), no conversions are allowed.
This is kind of a chicken and egg problem. To deduce the template argument, it needs an actual instance of std::basic_string. To convert to the wrapped type, a conversion target is needed. That target has to be an actual type, which a class template is not. The compiler would have to test all possible instantiations of std::basic_string against the conversion operator or something like that, which is impossible.
Suppose the following minimal testcase:
#include <functional>
template<class T>
struct foo{
int value;
};
template<class T>
bool operator<(foo<T> const& lhs, foo<T> const& rhs){
return lhs.value < rhs.value;
}
// comment this out to get a deduction failure
bool operator<(foo<int> const& lhs, foo<int> const& rhs){
return lhs.value < rhs.value;
}
int main(){
foo<int> f1 = { 1 }, f2 = { 2 };
auto ref1 = std::ref(f1), ref2 = std::ref(f2);
ref1 < ref2;
}
If we don't provide the overload for an instantiation on int, the deduction fails. If we provide that overload, it's something the compiler can test against with the one allowed user-defined conversion (foo<int> const& being the conversion target). Since the conversion matches in this case, overload resolution succeeds and we got our function call.
std::reference_wrapper does not have an operator<, so the only way to do ref_wrapper<ref_wrapper is via the ref_wrapper member:
operator T& () const noexcept;
As you know, std::string is:
typedef basic_string<char> string;
The relevant declaration for string<string is:
template<class charT, class traits, class Allocator>
bool operator< (const basic_string<charT,traits,Allocator>& lhs,
const basic_string<charT,traits,Allocator>& rhs) noexcept;
For string<string this function declaration template is instantiated by matching string = basic_string<charT,traits,Allocator> which resolves to charT = char, etc.
Because std::reference_wrapper (or any of its (zero) bases classes) cannot match basic_string<charT,traits,Allocator>, the function declaration template cannot be instantiated into a function declaration, and cannot participate in overloading.
What matters here is that there is no non-template operator< (string, string) prototype.
Minimal code showing the problem
template <typename T>
class Parametrized {};
template <typename T>
void f (Parametrized<T>);
Parametrized<int> p_i;
class Convertible {
public:
operator Parametrized<int> ();
};
Convertible c;
int main() {
f (p_i); // deduce template parameter (T = int)
f (c); // error: cannot instantiate template
}
Gives:
In function 'int main()':
Line 18: error: no matching function for call to 'f(Convertible&)'
Standard citations
14.8.2.1 Deducing template arguments from a function call [temp.deduct.call]
Template argument deduction is done by comparing each function template parameter type (call it P) with the type of the corresponding argument of the call (call it A) as described below.
(...)
In general, the deduction process attempts to find template argument values that will make the deduced A identical to A (after the type A is transformed as described above). However, there are three cases that allow a difference:
If the original P is a reference type, the deduced A (i.e., the type referred to by the reference) can be more cv-qualified than the transformed A.
Note that this is the case with std::string()<std::string().
The transformed A can be another pointer or pointer to member type that can be converted to the deduced A via a qualification conversion (4.4).
See comment below.
If P is a class and P has the form simple-template-id, then the transformed A can be a derived class of the deduced A.
Comment
This implies that in this paragraph:
14.8.1 Explicit template argument specification [temp.arg.explicit]/6
Implicit conversions (Clause 4) will be performed on a function argument to convert it to the type of the corresponding function parameter if the parameter type contains no template-parameters that participate in template argument deduction.
the if should not be taken as a if and only if, as it would directly contradict the text quoted previously.