deducing function template specialization when taking address - c++

I'm trying to understand the rules for function template argument deduction in the case where all arguments are defaulted. Under 13.10.1 (Explicit template argument specification), the standard (C++20) says:
— when the address of a function is taken, when a function initializes a reference to function, or when a pointer to member function is formed, ... If all of the template arguments can be deduced, they may all be omitted; in this case, the empty template argument list <> itself may also be omitted.
However, in the fourth line of the code snippets below, compilers (gcc, MSVC) seem to insist on having the empty angle brackets. Is this non-conformance or have I missed something ? (In this example, the issue doesn't matter, but the question arose in a context where it does matter).
template <typename T = int> void f(T) {}
void (*p)(int) = f; //ok
auto a = f<>; //ok
auto b = f; //error, can't deduce
void g() {}
auto c = g; //OK

The compilers are correct: auto a = f<>; is well-formed and auto b = f; is ill-formed. This is due to the rules about auto, combined with the rules about the address of the function template name f.
As described in [dcl.type.auto.deduct]/4, the auto type for the variable definitions is found in a way like template argument deduction done for a hypothetical function template using a template type parameter in its function parameter:
template <typename U> void auto_deducer(U);
auto a = f<>; // auto becomes the U deduced for auto_deducer(f<>)
auto b = f; // auto becomes the U deduced for auto_deducer(f)
In [temp.deduct.type] paragraphs 4 and 5:
In certain contexts, however, the value [of a template argument] does not participate in type deduction, but instead uses the values of template arguments that were either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.
The non-deduced contexts are:
...
A function parameter for which the associated argument is an overload set, and one or more of the following apply:
...
the overload set supplied as an argument contains one or more function templates.
...
So for both a and b, the template argument deduction used to determine the type of auto fails. Since it's not true that "all of the template arguments can be deduced", we're not allowed to omit the empty <> syntax.
But we're not entirely done yet, because the same paragraph [temp.arg.explicit]/4 you quoted has some relevant additional text:
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.... If all of the template arguments can be deduced, they may all be omitted; in this case, the empty template argument list <> itself may also be omitted. 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.
For the definition of both a and b, the f<> or f expression is in a non-deduced context, so "deduction is not done". (The template argument deduction for the hypothetical auto_deducer(f<>) then fails, but that's for the overall auto_deducer call, after the part actually involving f<> determined that the type deduction step should not be done with that argument at all.) In auto a = f<>;, "a template argument list is specified" and using the default template argument "identifies a single function template specialization" f<int>, so the paragraph's final sentence applies and the template-id names f<int> after all. In auto b = f; no template argument list is specified (and f is not a template-id), so the sentence can't apply.
An actual call like the statement f(); is fine because template argument deduction happens, uses the default template argument, and succeeds without the complication of auto. Converting expression f to a specific target pointer-to-function type is fine, because that will deduce the template parameter T from the target type, and the default template argument doesn't get involved.
Another confirmation this behavior is intended is found in a non-normative note in [over.over]/3. The [over.over] section applies when lookup for a name (like f or f<>) gives an overload set comprising one or more functions and/or function templates and the name expression is not followed by a function call argument list:
For each function template designated by the name, template argument deduction is done, 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 selected 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 ]

Trailing template arguments that can be deduced or obtained from default template-arguments
may be omitted from the list of explicit template-arguments. [...] If all of the template
arguments can be deduced, they may all be omitted; in this case, the empty template argument list <>
itself may also be omitted.
Note the last sentence, as opposed to the first sentence, does not say "deduced or obtained from default template-arguments". Deducing and obtaining from default template-arguments are two different things. This may or may not be a wording defect in the standard.

Related

Why does the compiler try to deduce when an argument-less function template is provided?

template <typename... T>
struct X {
static_assert(sizeof...(T) != 0);
};
template <typename... T>
void f(const X<T...> &) {}
template <typename T>
void inner() {}
int main() {
f(inner);
}
The static assert fires in this example.
Why does the compiler try to deducing anything here? And then it apparently even tries to instantiate X (with empty type argument list?..)...
Why the error isn't just 'template used without arguments'?..
If I change inner function to be a struct, the compiler reports:
use of class template 'inner' requires template arguments
which makes sense; if the param is just const X &, there's
declaration type contains unexpanded parameter pack 'T'
which also makes sense, however is less clear than the case with struct, because it reports an issue at the callee, not at the call site.
If the param is const X<T> &, the report is also a bit weird at first sight:
candidate template ignored: couldn't infer template argument 'T'.
These errors are for Clang 14, but GCC also reports similar ones.
Is the instantiation here somehow specified by the standard? If so, how? Also, why does it result in an empty type list?
This is mostly due to [temp.arg.explicit]/4, applicable when source names a function template, and emphasis mine:
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 not otherwise deduced will be deduced as an empty sequence of template arguments. If all of the template arguments can be deduced, they may all be omitted; in this case, the empty template argument list <> itself may also be omitted.
The function template name as an argument means it is not used for template argument deduction of f ([temp.deduct.type]/(5.5.3)). So the pack T is not deduced from the function argument list (inner), and [temp.arg.explicit]/4 applies and deduces T as an empty list of types.
Now to evaluate the expression f(inner) involves converting the expression inner to the parameter type const X<>&. Whether and how this is valid depends on the constructors of class X<>, so the template is instantiated, causing the static_assert error since the template parameter pack does have zero elements.
Because the argument refers to an overload set that contains a function template X, no deduction is attempted from it. The hope is that the deduction will succeed anyway (perhaps from other arguments) and then the template arguments of X can be deduced from the resulting argument type. (Of course, it’s impossible to deduce the template argument for inner, but even that of
template<class T>
T make();
can be deduced in certain contexts, so it’s not in general a vain hope.)
Here, deduction for f does succeed vacuously, with T as an empty pack. (This is much like a default template argument.) Then const X<>& is the parameter type, and so overload resolution is attempted to construct an X<> from inner. That obviously depends on the constructors for X<>, so that type is completed and the compilation fails.

What is the normative rule in the current draft rules that a template parameter pack which does not participate in deduction is deduced to empty

template<typename ...T, typename U>
void fun(U){}
int main(){
fun(0);
}
This snippet code is accepted by both GCC and Clang. The template parameter pack T does not participate in the template argument deduction in the context of function call, as per the following rules:
[temp.deduct.call]
Template argument deduction is done by comparing each function template parameter type (call it P) that contains template-parameters that participate in template argument deduction with the type of the corresponding argument of the call (call it A) as described below.
The pack T is contained by any function template parameter. If there were no other special rules specify, the deduction would fail according to:
[temp.deduct.type#2]
if any template argument remains neither deduced nor explicitly specified, template argument deduction fails.
However, such a case is ruled by the following rule in the current standard, that is:
[temp.arg.explicit#4]
A trailing template parameter pack ([temp.variadic]) not otherwise deduced will be deduced as an empty sequence of template arguments.
So, the above case can be considered to deduce successfully which leaves the pack T with an empty set of template arguments.
However, the special rule in temp.arg.explicit#4 has been changed to a note in the current draft
[temp.arg.explicit#note-1]
[Note 1: A trailing template parameter pack ([temp.variadic]) not otherwise deduced will be deduced as an empty sequence of template arguments. — end note]
So, I wonder Is there any alternative normative rule in the current draft states that the pack T not otherwise deduced will be deduced to an empty set of template arguments?
The previously normative section of [temp.arg.explicit]/4
[...] A trailing template parameter pack ([temp.variadic]) not otherwise deduced will be deduced as an empty sequence of template arguments. [...]
was made into a non-normative note as part of P1787R6.
As you've pointed out, as per [temp.deduct.type]/2 [emphasis mine]:
Type deduction is done independently for each P/A pair [...], if any template argument remains neither deduced nor explicitly specified, template argument deduction fails.
[temp.arg.general] describes that a template parameter that is a template parameter pack may correspond to zero template arguments:
[...] When the parameter declared by the template is a template parameter pack, it will correspond to zero or more template-arguments.
and [temp.variadic]/1 explicitly mention that a template parameter pack may accept zero arguments:
A template parameter pack is a template parameter that accepts zero or more template arguments.
followed by a non-normative example of an empty argument list for an entity templated over a parameter pack template parameter:
template<class ... Types> struct Tuple { };
Tuple<> t0; // Types contains no arguments
Now, returning to [temp.arg.explicit]/4:
If all of the template arguments can be deduced, they may all be omitted; in this case, the empty template argument list <> itself may also be omitted.
Meaning the Tuple example above is can likewise omit the empty argument list
Tuple t0; // Also OK: Types contains no arguments
but where the key is that, as per [temp.arg.general] above, that a template parameter list may correspond to zero arguments, in which case there are no template arguments needed to be deduced.
If you look at your own example:
template<typename ...T, typename U>
void fun(U){}
int main(){
fun(0); // #1
}
you could likewise invoke #1 as:
fun<>(0); // argument list for parameter pack is empty
// -> no argument (beyond that for `U`) to deduce
highlighting that the deducible argument corresponding to the template parameter U can be omitted from the explicit template-arguments, whereas the remaining template-arguments are none; namely, the argument list for the template parameter that is a template parameter pack is empty, and there are thus no remaining template arguments that needs to be deduced.
Thus
A trailing template parameter pack ([temp.variadic]) not otherwise deduced will be deduced as an empty sequence of template arguments.
is non-normative/redundant, explaining why it was wrapped into a [Note - [...] - end note].

When to supply default arguments as template arguments

template<typename T, typename U = T>
struct Test{};
template<typename T>
void func(Test<T>){ //#1
}
int main(){
func(Test<int>{}); //#2
}
It seems to no rule in the standard that mentioned what situation the default argument is required for template-parameter.
In dcl.fct.default#1
If an initializer-clause is specified in a parameter-declaration this initializer-clause is used as a default argument. Default arguments will be used in calls where trailing arguments are missing.
In this section, the rule explicitly describe when to supply default arguments for a function call. However I haven't found a quote in the standard similar with the above sentence that describes when to supply default arguments as template arguments.
Such as Test<T> at #1. Maybe at #1, the specialization would be Test<T,T>, It's just inference. However, there's no formally terminology explicitly describe this in the standard.
The only quote that implies the default arguments as template arguments is in the following rule:
temp#arg-8
When a simple-template-id does not name a function, a default template-argument is implicitly instantiated when the value of that default argument is needed. [ Example:
template<typename T, typename U = int> struct S { };
S<bool>* p; // the type of p is S<bool, int>*
The default argument for U is instantiated to form the type S<bool, int>*.  — end example ]
Consider the code at #1, Does the default argument need at #1? If it is(It seems to It need at that point because If I don't specify a default argument for template parameter U, then at the point #1 will occur an error. see godbolt outcome), According to the above quote, the default template-argument need to be implicitly instantiated, However at this point, T is a template-parameter and the definition of such function template instantiate nothing(It's just a function template definition at this point). So, How does the quote interpret this?
There is also this paragraph inside [temp.names]:
A template-id is valid if
there is an argument for each non-deducible non-pack parameter that does not have a default template-argument,
So one could consider that a default-argument is needed means a default-argument is needed in order to make the template-id valid and that when there lacks a template argument, the argument is the default argument value. But I have not found anything explicit in the standard for class templates. For function template this is more explicit. Probably nobody pointed out this hole in the standard because this is a common pattern: default is used in place of what is not user provided. Maybe it will not be changed because the definition of default in the english dictionary is already given:
IT. the way that something will happen or appear automatically, especially on a computer, if you do not make any different choices
-- cambrige online dictionary
According to the above quote, the default template-argument need to be implicitly instantiated, However at this point, T is a template-parameter and the definition of such function template instantiate nothing(It's just a function template definition at this point). So, How does the quote interpret this?
The key is the difference between need of instantiation and when referenced. In the example from [temp.arg]/8, the default template argument for U is instantiated because it is needed for the instantiation of S<bool>, which unambiguously resolves to S<bool, int>. In the OP's own example, instantiation of the instantiation-dependent default template argument for U will only follow after overload resolution resolves void func(Test<T>) as the best viable overload and thus instantiates it. Just inspecting candidate overloads as part of overload resolution, however, will not lead to instantiation of any of the candidates nor any of the function template candidates parameters that are, themselves, templates. It will, however, be referencing said template parameters as part of the overload resolution process (discarding non-viable candidates).
From [temp.deduct]/1 [emphasis mine]:
When a function template specialization is referenced, all of the template arguments shall have values. The values can be explicitly specified or, in some cases, be deduced from the use or obtained from default template-arguments. [...]
For the OP's particular example, the former (instantiation) only occurs after overload resolution has finished and a best viable overload has been instantiated (which in turn instantiates the class template function argument). The latter (a function/class template specialization being referenced to), however, applies also during overload resolution, even when discarding candidates that are either not viable or not the best viable match, candidates that will never lead to instantiations.
From [temp.deduct]/2 [emphasis mine]:
When an explicit template argument list is specified, the template arguments must be compatible with the template parameter list and must result in a valid function type as described below; otherwise type deduction fails. Specifically, the following steps are performed when evaluating an explicitly specified template argument list with respect to a given function template:
(2.1) The specified template arguments must match the template parameters in kind (i.e., type, non-type, template). There must not be more arguments than there are parameters unless [...]
and from [temp.deduct]/6 [emphasis mine]:
At certain points in the template argument deduction process it is necessary to take a function type that makes use of template parameters and replace those template parameters with the corresponding template arguments. This is done at the beginning of template argument deduction when any explicitly specified template arguments are substituted into the function type, and again at the end of template argument deduction when any template arguments that were deduced or obtained from default arguments are substituted.
it is clear that as part of the "end of template argument deduction", any template arguments that have not been explicitly specified will be either deduced or obtained from default arguments and substituted into the candidate function before discarding or ranking it as a viable overload. This applies without any relation to instantiation, and only in the context of a given specialization (that may not yet or ever be instantiated) being referenced, as part of overload resolution.
Finally, from [temp.deduct.type]/3 [emphasis mine]:
A given type P can be composed from a number of other types, templates, and non-type values:
[...]
(3.3) A type that is a specialization of a class template (e.g., A<int>) includes the types, templates, and non-type values referenced by the template argument list of the specialization.
we note that as part of function template argument deduction for a function template parameter that is a specialization of a class template, the function template parameter type (used for deduction against an argument) includes the types referenced by the template argument list of the template parameter, meaning the particular class template specialization (function template argument) is referenced, so that, as per [temp.deduct]/1, it will go through template argument deduction and default-argument inspection for any of its template arguments that are not explicitly specified.

How does the template argument deduction perform for function template parameter when it is a class template with default argument

template<typename T, typename U = T>
struct Test{};
template<typename T>
void func(Test<T>){ //#1
}
int main(){
func(Test<int>{}); //#2
}
Consider the above code, At the point of invocation of function template func, the type of argument is Test<int,int>, When call the function template, template argument deduction will perform.
The rule of template argument deduction for function call is :
temp.deduct#call-1
Template argument deduction is done by comparing each function template parameter type (call it P) that contains template-parameters that participate in template argument deduction with the type of the corresponding argument of the call (call it A) as described below.
I'm pretty sure the type of A is Test<int,int>, however I'm not sure what the type of P here is. Is it Test<T> or Test<T,T>, According to the rule, It seems to the type of P here is Test<T>, then deduction process is performed to determine the value of T that participate in template argument deduction. Then according to these rules described as the following:
temp.deduct#call-4
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).
temp.deduct#5
When all template arguments have been deduced or obtained from default template arguments, all uses of template parameters in the template parameter list of the template and the function type are replaced with the corresponding deduced or default argument values.
Because the class template Test has a default argument, hence the deduced T is substituted into default argument. That means the deduced A is Test<int,int> and it is identical to Argument type Test<int,int>.
However, It's just my understanding. I'm not sure what type the P here is. If change the type of function argument to Test<int,double>, the outcome will report:
candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'double')
The outcome looks like as if the P is Test<T,T> and the fist value of T is conflicting with the second value of T.
So, My question is:
Whether the P here is Test<T> or Test<T,T>? and why?
not a language lawyer answer
There is no type Test<T> is actually a "shorthand" for Test<T, T>.
Just like with default function arguments if you have int foo(int a, int b = 24) the type of the function is int (int, int) and any call like foo(11) is actually foo(11, 24).
P must be a type not a template. test <T> is a template-id, but it is not explicitly said in the standard that the template-id test <T> is equivalent to test<T,T>. The only thing that is said is:
A template-id is valid if
[...]
there is an argument for each non-deducible non-pack parameter that does not have a default template-argument, [...]
After that, holes in the standard are filled by our intuition oriented by the use of the term default.
I think the key point here is that a template designate a family, and a template-id cannot designate a family.
Whether the P here is Test<T> or Test<T,T>? and why?
P is Test<T,T>.
I think we can agree that the rules of [temp.deduct] applies also for class templates; e.g. [temp.class.order], covering partial ordering of class template specializations, is entirely based on the concept of re-writing the class templates to (invented) function templates and applying the rules of function templates to that of the invented function templates corresponding to the original class templates under partial ordering analysis. Combined with the fact that the standard passage for class templates is quite brief in comparison to function templates, I interpret the references below as applying also for class templates.
Now, from [temp.deduct]/1 [emphasis mine]:
When a function template specialization is referenced, all of the template arguments shall have values. The values can be explicitly specified or, in some cases, be deduced from the use or obtained from default template-arguments. [...]
and, from [temp.deduct]/2 [emphasis mine]:
When an explicit template argument list is specified, the template arguments must be compatible with the template parameter list and must result in a valid function type as described below; otherwise type deduction fails. Specifically, the following steps are performed when evaluating an explicitly specified template argument list with respect to a given function template:
(2.1) The specified template arguments must match the template parameters in kind (i.e., type, non-type, template). There must not be more arguments than there are parameters unless [...]
With extra emphasis on "is referenced" and "the specified template arguments"; there is no requirement that we specify all arguments for a given matching function(/class) template, only that those that do specify follow the requirements of [temp.deduct]/2 for explicitly specified template arguments.
This leads us to back to [temp.deduct]/1 for the remaining template arguments of a given candidate function/class template: these can be either deduced (function templates) or obtained from the default template arguments. Thus, the call:
func(Test<int>{});
is, as per the argument above, semantically equivalent to
func(Test<int, int>{});
with the main difference that the template arguments for the former is decided by both an explicitly specified template arguments and a default template argument, whereas for the latter both are decided by explicitly specified template arguments. From this, it is clear that A is Test<int, int>, but we will use a similar argument for P.
From [temp.deduct.type]/3 [emphasis mine]:
A given type P can be composed from a number of other types, templates, and non-type values:
[...]
(3.3) A type that is a specialization of a class template (e.g., A<int>) includes the types, templates, and non-type values referenced by the template argument list of the specialization.
Notice that the description in [temp.deduct.type]/3.3 now returns to the template argument list of the template type P. It doesn't matter that P, for when inspecting this particular candidate function in overload resolution, refers to a class template by partly explicitly specifying the template argument list and partly relying on a default template parameter, where the latter is instantiation-dependent. This step of overload resolution does not imply any kind of instantiation, only inspection of candidates. Thus, the same rules as we just applied to the template argument A above applies to P, in this case, and as Test<int, int> is referenced (via Test<int>), P is Test<int, int>, and we have a perfect match for P and A (for the single parameter-argument pair P and A of this example)
Compiler error messages?
Based in the argument above, one could arguably expect a similar error message for the OP's failing example:
// (Ex1)
template<typename T, typename U = T>
struct Test{};
template<typename T>
void func(Test<T>) {}
int main() {
func(Test<int, double>{});
}
as for the following simple one:
// (Ex2)
struct Foo {};
template<typename T> struct Test {};
template<typename T> void f(T) {}
int main() {
f<Test<int>>(Test<Foo>{});
}
This is not the case, however, as the former yields the following error messages for GCC and Clang, respectively:
// (Ex1)
// GCC
error: no matching function for call to 'func(Test<int, double>)'
note: template argument deduction/substitution failed:
deduced conflicting types for parameter 'T' ('int' and 'double')
// Clang
error: no matching function for call to 'func'
note: candidate template ignored: deduced
conflicting types for parameter 'T' ('int' vs. 'double')
whereas the latter yields the following error messages for GCC and Clang, respectively:
// (Ex2)
// GCC
error: could not convert 'Test<Foo>{}' from 'Test<Foo>' to 'Test<int>'
// Clang
error: no matching function for call to 'f'
note: candidate function template not viable:
no known conversion from 'Test<Foo>' to 'Test<int>' for 1st argument
We can finally note that if we tweak (Ex1) into explicitly specifying the single template argument of f, both GCC and Clang yields similar error messages as for (Ex2), hinting that argument deduction has been entirely removed from the equation.
template<typename T, typename U = T>
struct Test{};
template<typename T>
void func(Test<T>) {}
int main() {
func<int>(Test<int, double>{});
}
The key for this difference may be as specified in [temp.deduct]/6 [emphasis mine]:
At certain points in the template argument deduction process it is necessary to take a function type that makes use of template parameters and replace those template parameters with the corresponding template arguments. This is done at the beginning of template argument deduction when any explicitly specified template arguments are substituted into the function type, and again at the end of template argument deduction when any template arguments that were deduced or obtained from default arguments are substituted.
namely that the template argument deduction process is separated into a clear beginning and end, categorizing:
explicitly specified template arguments as the beginning of the process, and,
deduced or default argument-obtained template arguments as the end of the process,
which would explain the differences in the error messages of the examples above; if all template arguments have been explicitly specified in the beginning of the deduction process, the remainder of the process will not have any remaining template argument to work with w.r.t. deduction or default template arguments.
I tryed to come up with a code that forces only class deduction without function deduction.
Here, there are no function instantiations, but the compiler emits an error anyway:
template<typename T, typename U = T>
struct Test{};
template<typename T>
void func(Test<T, T>){
}
template<typename T>
void func(Test<T>){
}
redefinition of 'template<class T> void func(Test<T, T>)'
GCC: https://godbolt.org/z/7c981E
Clang:
https://godbolt.org/z/G1eKTx
Previous wrong answer:
P refers to template parameter, not to template itself. In declaration Test<typename T, typename U = T> P refers to T, not to Test. So in the instantiation Test<int> T is int, just like A in the call is also int.

Empty variardic packs of enums -- do they make two functions different?

There is a technique I sometimes use when overriding template functions that goes like this:
#include <utility>
template<int> struct unique_enum { enum class type {}; };
template<int index> using UniqueEnum = typename unique_enum<index>::type;
template<bool b, int index=1>
using EnableFuncIf = typename std::enable_if< b, UniqueEnum<index> >::type;
template<bool b, int index=1>
using DisableFuncIf = EnableFuncIf<!b, -index>;
// boring traits class:
template<typename T>
struct is_int : std::false_type {};
template<>
struct is_int<int> : std::true_type {};
#include <iostream>
// use empty variardic packs to give these two SFINAE functions different signatures:
template<typename C, EnableFuncIf< is_int<C>::value >...>
void do_stuff() {
std::cout << "int!\n";
}
template<typename C, DisableFuncIf< is_int<C>::value >...>
void do_stuff() {
std::cout << "not int!\n";
}
int main() {
do_stuff<int>();
do_stuff<double>();
}
This distinguishes do_stuff from do_stuff, because one takes 0 or more UniqueEnum<1>s, and the other takes 0 or more UniqueEnum<-1>s. gcc 4.8 considers these different empty packs to be distinct.
However, in the latest version of clang I tried, this fails: it treats the function with 0 UniqueEnum<1>s as being the same as the function with 0 UniqueEnum<-1>s.
There are easy workarounds that work in clang, but I'm wondering if my above technique is legal -- do two function templates, which differ only by empty variardic parameter packs, actually different?
I think GCC is right, and your technique is correct. Basically, since the type argument for C is specified explicitly, the question is whether:
a. substitution of C everywhere else in the function template signature happens first, and then type deduction is performed (which should result in a substitution failure); or
b. type deduction is performed first, and then substitution is performed (which would not result in a substitution failure, because the corresponding argument pack would be empty, and so there would be no substitution to perform).
It seems GCC assumes (1), while Clang assumes (2). Paragraph 14.8.2/2 of the C++11 Standard specifies:
When an explicit template argument list is specified, the template arguments must be compatible with the
template parameter list and must result in a valid function type as described below; otherwise type deduction
fails. Specifically, the following steps are performed when evaluating an explicitly specified template
argument list with respect to a given function template:
— The specified template arguments must match the template parameters in kind (i.e., type, non-type,
template). There must not be more arguments than there are parameters unless at least one parameter
is a template parameter pack, and there shall be an argument for each non-pack parameter. Otherwise,
type deduction fails.
— Non-type arguments must match the types of the corresponding non-type template parameters, or must
be convertible to the types of the corresponding non-type parameters as specified in 14.3.2, otherwise
type deduction fails.
— The specified template argument values are substituted for the corresponding template parameters as
specified below.
The following paragraph then says:
After this substitution is performed, the function parameter type adjustments described in 8.3.5 are performed. [...]
Moreover, paragraph 14.8.2/5 specifies:
The resulting substituted and adjusted function type is used as the type of the function template for template
argument deduction. [...]
Finally, paragraph 14.8.2/6 goes as follows:
At certain points in the template argument deduction process it is necessary to take a function type that
makes use of template parameters and replace those template parameters with the corresponding template
arguments. This is done at the beginning of template argument deduction when any explicitly specified template
arguments are substituted into the function type, and again at the end of template argument deduction
when any template arguments that were deduced or obtained from default arguments are substituted.
This all seems to imply that first substitution is performed, then template argument deduction. Hence, a substitution failure should occur in either case and one of the two templates should be discarded from the overload set.
Unfortunately, there does not seem to be a clear specification as to what the behavior should be when templates arguments are deduced rather than being explicitly specified.