This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115g. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-12-16
[Accepted as a DR at the March, 2018 (Jacksonville) meeting.]
Given an example like
template <class T = int> void foo(T*); void test() { foo(0); // #1 valid? foo<>(0); // #2 valid? }
most/all implementations reject this code. However, the wording of the Standard only invokes 13.10.4 [temp.over] (“Overload resolution”) in cases where there is more than one function or function template, which is not the case here. The current wording would appear to make this well-formed because of the application of 13.10.2 [temp.arg.explicit] paragraph 2. Perhaps overload resolution should apply even when there is a single function template?
Notes from the May, 2015 meeting:
This issue is mostly a duplicate of issue 1582. However, CWG felt that it should be clarified that overload resolution applies in all cases, not just when templates are overloaded, so the issue is being left open to deal with that aspect.
Proposed resolution (November, 2017)
Change 7.6.1.3 [expr.call] paragraph 1, splitting it into three paragraphs, as follows:
A function call is a postfix expression followed by parentheses containing a possibly empty, comma-separated list of initializer-clauses which constitute the arguments to the function. The postfix expression shall have function type or function pointer type. For a call to a non-member function or to a static member function, the postfix expression shall be either an lvalue that refers to a function (in which case the function-to-pointer standard conversion (7.3.4 [conv.func]) is suppressed on the postfix expression), or it shall have function pointer type.
Calling a function through an expression whose function type is different from the function type of the called function's definition results in undefined behavior (9.11 [dcl.link]).For a call to a non-static member function, the postfix expression shall be an implicit (11.4.3 [class.mfct.non.static], 11.4.9 [class.static]) or explicit class member access (7.6.1.5 [expr.ref]) whose id-expression is a function member name, or a pointer-to-member expression (7.6.4 [expr.mptr.oper]) selecting a function member; the call is as a member of the class object referred to by the object expression. In the case of an implicit class member access, the implied object is the one pointed to by this. [Note: A member function call of the form f() is interpreted as (*this).f() (see 11.4.3 [class.mfct.non.static]). —end note]
If a function or member function name is used,
the name can be overloaded (Clause 12 [over]), in which casethe appropriate functionshall be selectedand the validity of the call are determined according to the rules in 12.2 [over.match]. If the selected function is non-virtual, or if the id-expression in the class member access expression is a qualified-id, that function is called. Otherwise, its final overrider (11.7.3 [class.virtual]) in the dynamic type of the object expression is called; such a call is referred to as a virtual function call. [Note: The dynamic type is the type of the object referred to by the current value of the object expression. 11.9.5 [class.cdtor] describes the behavior of virtual function calls when the object expression refers to an object under construction or destruction. —end note]
Add the following to 7.6.1.3 [expr.call] as a new paragraph before the existing paragraph 4:
Calling a function through an expression whose function type is different from the function type of the called function's definition results in undefined behavior (9.11 [dcl.link]).
When a function is called, each parameter (9.3.4.6 [dcl.fct]) shall be initialized...
Change Clause 12 [over] paragraph 2 as follows:
Whenan overloadeda function name is used in a call, whichoverloadedfunction declaration is being referencedisand the validity of the call are determined by comparing the types of the arguments at the point of use with the types of the parameters in theoverloadeddeclarations that are visible at the point of use. This function selection process is called overload resolution...
Change 13.10.4 [temp.over] paragraph 1 as follows:
A function template can be overloaded either by (non-template) functions of its name or by (other) function templates of the same name.When a call tothatthe name of a function or function template is written (explicitly, or implicitly using the operator notation), template argument deduction...
This resolution also resolves issue 2241.