Bug 87629 - function template parameter deduction succeeds but parameter and deduced arg does not match.
Summary: function template parameter deduction succeeds but parameter and deduced arg ...
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 8.2.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid
Depends on:
Blocks:
 
Reported: 2018-10-17 08:04 UTC by Olivier Kannengieser
Modified: 2018-10-18 12:15 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Olivier Kannengieser 2018-10-17 08:04:20 UTC
This bug is present in all gcc versions.

Consider the following code:

    template<class...Args>
    struct x{
        x(void(*)(int));
    };
    
    void foo(int);
    
    template<class T>
    void Tfoo(T);
    
    template<class...Args>
    void x_func(x<Args...> a);
    
    void test(){
      x_func(foo);   //does not compile => standard compliant
      x_func(Tfoo); //compile! template deduction + conversion => not standard compliant
      }

`x_func(Tfoo)` compiles, but this violate this standard rule [\[temp.deduct.call\]/4](http://eel.is/c++draft/temp.deduct#call-4) which states that the deduced function argument type shall match (almost) the type of the argument:

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 function pointer conversion and/or qualification conversion.

>  - 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.

See also this stackoverflow question:https://stackoverflow.com/q/52845621/5632316
Comment 1 Olivier Kannengieser 2018-10-18 07:59:18 UTC
This is maybe not a compiler bug, to be confirmed/unconfirmed by an expert of the standard.
Comment 2 Olivier Kannengieser 2018-10-18 11:26:50 UTC
This is not a bug, this bug report should be removed!

The function call is undeduced context so the rule [temp.call.deduct]/4 is bypassed.
Comment 3 Jonathan Wakely 2018-10-18 12:15:05 UTC
Agreed, the call to x_func(Tfoo) deducing Args as an empty pack, and then deduces T as int for the argument to the x<>::x(void(*)(int)) constructor.