When I have multiple templates that could be instantiated, what happens?
template <typename T> void foo(T*);
template <typename T> void foo(T**);
template void foo(int**);
template <typename T> void foo(T*) { printf("called foo(T*)\n"); }
template <typename T> void foo(T**){ printf("called foo(T**)\n"); }
When we need to instantiate a foo(int**), either of the instantiations would work, one with T=int* and the other with T=int**. In practice, the object file only contains one, the T** one. On the other hand, if I put a static_assert(false) into the unused one, the compilation fails. Does that mean that it is instantiated?
It turns out that the T** is the one that I want to use in this case. But even if both were instantiated, overload resolution would pick the T** one, so this works for me either way.
Now in my actual code, I request two instantiations:
template void foo(int*);
template void foo(int**);
That instantiates foo<int>(int**) and foo<int>(int*), so I get both templates. The latter is forced, since template <typename T> foo(T**) doesn't match. But I don't understand the rules to know why I don't get foo<int*>(int**) for the former. Or both foo<int*>(int**) as well as foo<int>(int**).
And yes, I realize I could do template void foo<int*>(int**) if I needed to force it.
All this makes me realize I don't really understand what happens when the compiler sees a call that requires a template instantiation. Does it scan through templates until it finds one that works, then stop? Or does it instantiate all valid options (and then something discards the unneeded ones from the object file)?
Template argument deduction is performed to figure out what function template specialization is named by template void foo(int**);; it selects the T** one after considering partial ordering. See [temp.deduct.decl] and sections linked therein. That's roughly the same process used to pick the function template to call during overload resolution (with some minor differences).
There's no mechanism for instantiating everything that matches. If the compiler can't select a unique function template specialization, the program is simply ill-formed.
On the other hand, if I put a static_assert(false) into the unused one, the compilation fails. Does that mean that it is instantiated?
That's just [temp.res]/8 at work, as usual. Code that is ill-formed in a way that doesn't depend on a template parameter may be diagnosed immediately without instantiation.
if I put a static_assert(false) into the unused one, the compilation fails. Does that mean that it is instantiated?
No. The compiler does some basic checks on a template definition. Everything in the definition must be valid C++, but certain things which depend on a template parameter cannot be checked until an actual instantiation, when the template arguments are known. Since static_assert(false); does not depend on any template parameters, it always causes an error, and a compiler is allowed to note the error even when the template is never instantiated.
If you really want a template that should never be instantiated, the usual way is to use =delete for a function template, or leave a class template undefined.
But I don't understand the rules to know why I don't get foo<int*>(int**) for the former.
In most contexts that name a specialization of a function template, there's a rule that any template which is "more specialized" than all other viable overloads is the one that gets used. The exact definition of "more specialized" is a bit tricky, but the basic idea is that if any argument list that could be taken by a function template "A" could also be taken by a function template "B" but not vice versa, then "A" is more specialized. In your example
template <typename T> void foo(T*); // #1
template <typename T> void foo(T**); // #2
if an argument arg has type U** for any type U so that template argument deduction for template #2 for foo(arg) can succeed with T=U, we can see that template argument deduction for template #1 for foo(arg) can also succeed with T=U*. On the other hand, it's obviously possible that another argument arg2 can mean that template argument for foo(arg2) can succeed for template #1 but fail for template #2, for example if arg2 has type int*. So function template #2 is more specialized than function template #1. This means an expression like foo(arg), whenever type deduction for both succeeds (and there are no other viable overloads involved), means a use of template #2.
The same "more specialized" rule applies in your explicit instantiation
template void foo(int**);
Much like with a function call expression, the compiler will use template argument deduction to see whether the declaration you gave matches each function template. In this case both succeed, but since template #2 is more specialized, the declaration is interpreted as a specialization of #2 and not #1.
All this makes me realize I don't really understand what happens when the compiler sees a call that requires a template instantiation. Does it scan through templates until it finds one that works, then stop? Or does it instantiate all valid options (and then something discards the unneeded ones from the object file)?
The rough sequence for most uses of the name of an overloaded function template is:
Do name lookup to determine the list of function templates and functions to be considered.
For each function template in the list, attempt template argument deduction. If template argument deduction fails, or if substituting any template argument into the function type fails, ignore that template from here on. If successful, this results in a template argument for each template parameter, and one specific function type for the specialization.
Do overload resolution in mostly the same way as for non-templates, on the set of non-template functions initially looked up combined with the set of function template specializations determined above. But if two candidate functions cannot be ordered to say one is a better overload than the other just based on the parameter types and implicit conversions involved, then a non-template function beats a function template specialization, and a specialization from a more specialized function template beats a specialization from a less specialized function template.
Note that during this process, the function types but not the definitions of the function template specializations are instantiated.
Related
Recently I reported a msvc bug involving a function parameter pack. Also as it turns out here that msvc is actually standard compliant there.
Then when I modified the example to what is shown below I noticed that the modified code also cannot be compiled in msvc but can be compiled in clang and gcc. The code is as follows: Demo link
template<typename T> struct C{};
template<typename T> void f(C<T>)
{
}
template<typename... T> void f(C<T...>)
{
}
int main()
{
f(C<int>{}); //Should this call succeed?
}
Note that in the above example we have as the function parameter C<T...> as opposed to just T.... Now, in the above shown example, I am not 100% sure that if it is a msvc issue or the standard disallows the program.
So my question is, is the above shown code example well formed. That is, should the call f(C<int>{}); succeed choosing the first overload void f(C<T>) instead of void f(C<T...>)?
In other words, which compiler is right here.
So my question is, is the above shown code example well formed.
The code is well-formed as the function template overload with a non-variadic template parameter is more specialized than the overload with a variadic template parameter, by partial ordering rules.
MSVC is incorrect to reject it.
[temp.func.order]/1 through /4 tells us that we need to turn to partial ordering
/1 If a function template is overloaded, the use of a function template
specialization might be ambiguous [...]. Partial ordering of overloaded function template declarations is used in the following contexts to select the function template to which a function template specialization refers:
/1.1 during overload resolution for a call to a function template specialization ([over.match.best]);
[...]
/2 Partial ordering selects which of two function templates is more specialized than the other by transforming each template in turn (see next paragraph) and performing template argument deduction using the function type. [...] If so, the more specialized template is the one chosen by the partial ordering process. If both deductions succeed, the partial ordering selects the more constrained template (if one exists) as determined below.
/3 To produce the transformed template, for each type, non-type, or template template parameter (including template parameter packs
thereof) synthesize a unique type, value, or class template
respectively and substitute it for each occurrence of that parameter
in the function type of the template.
/4 Using the transformed function template's function type, perform type deduction against the other template as described in [temp.deduct.partial].
[temp.deduct.partial]
/2 Two sets of types are used to determine the partial ordering. For each of the templates involved there is the original function type
and the transformed function type. The deduction process uses the
transformed type as the argument template and the original type of the
other template as the parameter template. [...]
/4 Each type nominated above from the parameter template and the corresponding type from the argument template are used as the types of
P and A.
/8 Using the resulting types P and A, the deduction is then done as described in [temp.deduct.type]. [...] If deduction succeeds for a given type, the type from the argument template is considered to be at least as specialized as the type from the parameter template.
results in, for the original single function parameter function templates, the following P/A pairs:
P A
-------- ----------
#1: C<T> C<Unique1...>
#2: C<T...> C<Unique2>
Typically, when not in the context of partial ordering, deduction would succeed for both these pairs. However, [temp.deduct.type]/9 has a special case for when the deduction is performed as part of partial ordering:
/9 [...] During partial ordering, if Ai was originally a pack expansion:
/9.2 otherwise, if Pi is not a pack expansion, template argument deduction fails.
This clause means deduction of #1 above (C<T> from C<Unique1...>) fails, whereas #2 (C<T...> from C<Unique2>) succeeds and C<Unique2> is considered at least as specialized as C<T...>. As per [temp.deduct.partial]/10 the non-variadic function template overload is thus at least as specialized as the variadic template function overload and, in the absense of the vice-versa relationsship, moreover more specialized:
/10 Function template F is at least as specialized as function template G if, for each pair of types used to determine the ordering,
the type from F is at least as specialized as the type from G. F is
more specialized than G if F is at least as specialized as G and G is
not at least as specialized as F.
This leads us back to [temp.func.order]/2 and the more specialized function template is chosen by partial ordering:
/2 [...] The deduction process determines whether one of the templates is more specialized than the other. If so, the more specialized template is the one chosen by the partial ordering process.
Which is also covered by [over.match.best]/2.5
/2 Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments
i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then
[...]
/2.5 F1 and F2 are function template specializations, and the function template for F1 is more specialized than the template for F2
according to the partial ordering rules described in
[temp.func.order], or, if not that, [...]
#include <iostream>
template<typename T>
void test(T,typename T::type){ //#1
}
template<typename T,typename U>
void test(T,U){ //#2
}
int main(){
test(0,0); //we know #2 is called
}
consider above code,to call function test for arguments 0,0,the complier need to find the best match overload for these arguments and instantiate the function template,firstly,there are two function template named test,the complier deduce the template paraments from arguments for them. I want to know the instantiation or the substitution which is first performanced on the function template in the next step?whether the overload resolution is performanced after them?
when to instantiate function template
If you call the name of an overloaded function template, the compiler will try to deduce its template arguments and check its explicitly declared template arguments. If successful, it will instantiate a function template specialization, then add this specialization to the set of candidate functions used in overload resolution
when to perform substitution
Specifically, when creating a candidate set for overload resolution, some (or all) candidates of that set may be the result of instantiated templates with (potentially deduced) template arguments substituted for the corresponding template parameters. If an error occurs during the substitution of a set of arguments for any given template, the compiler removes the potential overload from the candidate set instead of stopping with a compilation error, provided the substitution error is one the C++ standard grants such treatment
I have not found the document about the order of substitution and instantiation
UPDATE:
the deduction,substitution(the sfinae is happened here) is parts of instantiation,however,except these,generate defination by substituting template arguments at the point of instantiation also a part of instantiation,when does it happen?after overload resolution or after the substitution(here is the sfinae)?
Your example doesn't show much regarding your question as there is only one viable candidate: Substitution fails for #1 as int::type is ill-formed, and thus there is only one function, #2.
On the other hand, it does mean that parameter substitution has to happen as part of the instantiation (as noted by #IgorTandetnik). And, for there to be any overloads to resolve, template instantiation has to happen before.
If you change #1 to
template <typename T>
void test(T,T){}
you would have two viable overloads, and #1 would be selected.
Edit:
On the other hand, if you change your main function to
struct {
using type = int;
int val = 0;
} x;
test(x,0);
both templates will be instantiated but overload resolution will fail as the two functions void test(anonymous struct, int) are ambiguous.
That also illustrates that the templates must be instantiated before overload resolution can take place.
I have two template operators in class:
template<class T>
size_t operator()(const T& t) const {
static_assert(boost::is_pod<T>(), "Not a POD type");
return sizeof t;
}
template<typename... T>
size_t operator()(const boost::variant<T...>& t) const
{
return boost::apply_visitor(boost::bind(*this, _1), t);
}
I pass boost::variant<some, pod, types, here> as an argument to these operators. GCC 4.8 and llvm 6.0 compile the code fine, choosing boost::variant parameterized operator. gcc 4.7 chooses const T& t parameterized operator and thus fails to compile due to static assert.
So, I have a question, what are the rules for choosing between these two?
I think gcc 4.7 must have a bug, but I don't have any proof.
The key section is in [temp.deduct.partial]:
Two sets of types are used to determine the partial ordering. For each of the templates involved there is
the original function type and the transformed function type. [ Note: The creation of the transformed type
is described in 14.5.6.2. —end note ] The deduction process uses the transformed type as the argument
template and the original type of the other template as the parameter template. This process is done twice
for each type involved in the partial ordering comparison: once using the transformed template-1 as the
argument template and template-2 as the parameter template and again using the transformed template-2
as the argument template and template-1 as the parameter template.
That's really dense, even for the C++ standard, but what it basically means is this. Take our two overloads:
template <class T> // #1
size_t operator()(const T& t) const
template <typename... T> // #2
size_t operator()(const boost::variant<T...>& t)
And we're going to basically assign some unique type(s) to each one and try to see if the other applies. So let's pick some type A for the #1, and B,C,D for #2. Does operator()(const A&) work for #2? No. Does operator()(const boost::variant<B,C,D>&) work for #1? Yes. Thus, the partial ordering rules indicate #2 is more specialized than #1.
And so, from [temp.func.order]:
The deduction process determines whether one of the templates is more specialized than the other. If
so, the more specialized template is the one chosen by the partial ordering process.
And from [over.match.best]:
[A] viable function F1 is defined to be a better function than another viable function
F2 if
— [..]
— F1 and F2 are function template specializations, and the function template for F1 is more specialized
than the template for F2 according to the partial ordering rules described in 14.5.6.2.
Thus, #2 should be chosen in any case where it applies. If GCC chooses #1, that is nonconforming behavior and is a bug.
In general the compiler just treats all deduced template instantiations as potential overloads, picking the "best viable function" (§ 13.3.3).
Indeed this means GCC 4.7 has a bug then.
See §14.8.3: Overload resolution
describes that all template instances will join in the set of candidates as any non-template declared overload:
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 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. For each function template, if the argument deduction and
checking succeeds, the template- arguments (deduced and/or explicit) are used
to synthesize the declaration of a single function template specialization
which is added to the candidate functions set to be used in overload
resolution. If, for a given function template, argument deduction fails, no
such function is added to the set of candidate functions for that template. The
complete set of candidate functions includes all the synthesized declarations
and all of the non-template overloaded functions of the same name. The
synthesized declarations are treated like any other functions in the remainder
of overload resolution, except as explicitly noted in 13.3.3.
In the case of your question, the overloads end up being indistinguishable (credit: #Piotr S). In such cases "partial ordering" is applied (§14.5.6.2):
F1 and F2 are function template specializations, and the function template for F1 is more specialized than the template for F2
Note that things can get pretty tricky, when e.g. the "open template" version took a T& instead of T const& (non const references are preferred, all else being equal).
When you had several overloads that end up having the same "rank" for overload resolution, the call is ill-formed and the compiler will diagnose an ambiguous function invocation.
I'm aware that the compiler will not instantiation unused template functions as long as they are not virtual in a class.
In a simple case, if I have two overloaded template functions both of which take the same template arguments, it seems the compiler instantiates both overloads. I guess this is required so that the compiler can perform overload resolution? Are overloads exempt from the lazy-instantiation rule for function templates? I wasn't able to find the relevant text in the standard. Here is an example:
template<typename T>
void foo(T) {zzz}
template<typename T>
void foo(T*) {}
int main()
{
int* blah;
foo(blah);
}
I would expect no compiler error if the first overload was not instantiated, however I get the error.
Live Sample
It seems as though you're expecting only one of those overloads to be instantiated because only one of them will be called, but the compiler clearly has to instantiate both of them in order to determine whether either of them can be called and, if so, which one to use.
The more formal answer is that both templates are candidates because your T can always be pointerised, so both are "used" in that sense:
[C++14: 14.7.1/3]: Unless a function template specialization has been explicitly instantiated or explicitly specialized, the function template specialization is implicitly instantiated when the specialization is referenced in a context that requires a function definition to exist. Unless a call is to a function template explicit specialization or to a member function of an explicitly specialized class template, a default argument for a function template or a member function of a class template is implicitly instantiated when the function is called in a context that requires the value of the default argument.
[C++14: 14.7.1/10]: If a function template or a member function template specialization is used in a way that involves overload resolution, a declaration of the specialization is implicitly instantiated (14.8.3).
So, basically:
I guess this is required so that the compiler can perform overload resolution?
Correct.
Your question, however, already stems from a misconception that your first function template can be ignored: it can't be. zzz does not depend on any template parameters so SFINAE is not involved; even if SFINAE were involved, it could not help you with your invalid syntax. So, no matter what you do, that code is ill-formed:
template<typename T>
void nil() {zzz}
// g++ -c -std=c++11 -O2 -Wall -pedantic -pthread main.cpp
// main.cpp: In function 'void nil()':
// main.cpp:2:13: error: 'zzz' was not declared in this scope
// void nil() {zzz}
// ^
(live demo)
That being said, a diagnostic is not required in this case; in particular, Microsoft Visual Studio has historically silently accepted such code:
[C++14: 14.6/8]: Knowing which names are type names allows the syntax of every template to be checked. No diagnostic shall be issued for a template for which a valid specialization can be generated. If no valid specialization can be generated for a template, and that template is not instantiated, the template is ill-formed, no diagnostic required. If every valid specialization of a variadic template requires an empty template parameter pack, the template is ill-formed, no diagnostic required. If a type used in a non-dependent name is incomplete at the point at which a template is defined but is complete at the point at which an instantiation is done, and if the completeness of that type affects whether or not the program is well-formed or affects the semantics of the program, the program is ill-formed; no diagnostic is required. [..]
The same wording may also be found in C++11 and C++03, so this has always been the case. Your misconception is therefore understandable.
Incidentally, your observation regarding virtual functions is also not completely accurate:
[C++14: 14.7.1/11]: An implementation shall not implicitly instantiate a function template, a variable template, a member template, a non-virtual member function, a member class, or a static data member of a class template that does not require instantiation. It is unspecified whether or not an implementation implicitly instantiates a virtual member function of a class template if the virtual member function would not otherwise be instantiated. The use of a template specialization in a default argument shall not cause the template to be implicitly instantiated except that a class template may be instantiated where its complete type is needed to determine the correctness of the default argument. The use of a default argument in a function call causes specializations in the default argument to be implicitly instantiated.
This is not an answer from the inner question, but it is related about the assumption of the question: "I would expect no compiler error if the first overload was not instantiated, however I get the error."
Sure? so, why this code generate a compiler error?
template<typename T>
void nil(T) {zzz}
template<typename T>
void foo(T*) {}
int main()
{
int* blah;
foo(blah);
}
because nil is not instantiated
In this article, they are saying (c) explicit specialization of (b). My doubt is why can't we say it is explicit specialization of (a) ? because we can specialize the template for any particular type. so while specializing for int*, why they say (c) explicit specialization of (b) .
template<class T> // (a) a base template
void f( T );
template<class T> // (b) a second base template, overloads (a)
void f( T* ); // (function templates can't be partially
// specialized; they overload instead)
template<> // (c) explicit specialization of (b)
void f<>(int*);
Any comments will be helpful to understand the things.
If (b) didn't exist, then (c) would indeed be a valid specialisation of (a). In fact, just changing the order of the source lines so that (c) appears before the compiler has seen (b) will make it a specialisation of (a)!
Consider the following code:
int main()
{
int a;
f(&a);
return 0;
}
Now put yourself in the compiler's shoes. You need to find a matching function f with an int* argument. What do you do?
First, you try all the non-template functions called f that you know about, and see if there are any which match the argument types (in this case, int*).
If you can't get a perfect match, you look at all the base templates that you know about. In this case, there are two: f<T> and f<T*>. Note that unlike classes, function templates can't be partially specialised, so as far as the compiler is concerned these are completely separate overloads.
Clearly the f<T*> base template is a better match, so you instantiate it with T=int. Now, if you've already seen a specialisation for f<int*>, then you use that, and otherwise you generate the function.
Now here's the funny thing. If we change the order of your original code, to
template<class T> void f( T ); // (i)
template<> void f<>(int*); // (ii)
template<class T> void f( T* ); // (iii)
then the compiler now sees (ii) as a specialisation of (i) -- because it processes things in order, and at the point it reaches (ii) it doesn't know that (iii) exists yet! But since it only matches on base templates, it decides that (iii) is a better match than (i) -- and now (iii) does not have any specialisations, so you get the default instantiation.
It's all pretty confusing, and can trip up even the most experienced C++ programmers at times. So the basic rule is this: don't specialise function templates, but use normal function overloading instead. A regular old, non-template
void f(int*);
would be matched before anything else, and avoids this whole mess.
EDIT: n.m. requested references to the standard in the comments. I'm afraid I only have the C++03 version to hand, but here goes:
Paragraph 4.7.3.3: "A declaration of a function template or class template being explicitly specialized shall be in scope at the point of declaration of an explicit specialization.".
That's why in the above example, (ii) cannot be considered as an explicit specialisation of (iii), because (iii) is not yet in scope.
Section 4.8.3: "When a call to that [function] name is written... 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."
In other words, (as I read it, anyway) it always looks at each base template no matter what -- providing an explicit specialisation makes no difference.
The same paragraph goes on: "For each function template, if the argument deduction and checking succeeds, the template-arguments (deduced and/or explicit) are used to instantiate a single function template specialization which is added to the candidate functions set to be used in overload resolution."
So it's only at this point (as I read it) that explicit specialisations get taken into account.
Lastly, and perhaps most importantly in this case, section 13.3.3 deals with choosing the "best viable function" in the overload set. Two items are relevant:
F1 is better than F2 if: "F1 and F2 are function template specializations, and the function template for F1 is more specialized than the template for F2 according to the partial ordering rules described in 14.5.5.2". This is why the f<T*> version gets picked ahead of the f<T> version when trying to match f(int*) -- because it's a "more specialised" template
F1 is better than F2 if: "F1 is a non-template function and F2 is a function template specialization", which was the basis for my advice at the end of the original answer.
Phew!