User:Mwe

C-Programming and Teaching since >30 years, C++ >20 years now.

My first C compiler came with Unix (XENIX), my first C++ compiler I bought from Comeau Computing in the early '90s - no g++ then, Zortech had a product for Windows but I was strickly *ix-ish then and still am. This compiler had neither templates, nor exceptions, nor a decent standard library for anything else but input and output.

The C++ world was neatly arranged then, nevertheless P.J. Plauger once (1993) wrote in the C/C++ Users Journal:

I confess that I still don't "get" C++ with anywhere near the depth that I understand C. I suspect I never will.

I often think of this when I start feeling a bit lost in certain areas of modern C++ (like template meta programming) ... at times when I find the language and its library overwhelming and impenetrable given the size it has reached ...

Trying the "look & feel" of the function template page with examples that compile:

To determine which of any two function templates is more specialized, the partial ordering process first transforms one of the two templates as follows:
 * For each type, non-type, and template parameter, including parameter packs, a unique fictitious type, value, or template is generated and substituted into function type of the template
 * If only one of the two function templates being compared is a non-static member of some class, a new first parameter is inserted into its parameter list, whose type is if the member function template is &&-qualified and  otherwise (cv is the cv-qualification of the member function template) -- this helps the ordering of operators, which are looked up both as member and as non-member functions:

After one of the two templates was transformed as described above, is executed using the transformed template as the argument template and the original template type of the other template as the parameter template. The process is then repeated using the second template (after transformations) as the argument and the first template in its original form as the parameter.

The types used to determine the order depend on the context:
 * in the context of a function call, the types are those function parameter types for which the function call has arguments (default function arguments, parameter packs, and ellipsis parameters are not considered -- see examples below)
 * in the context of a call to a user-defined conversion function, the return types of the conversion function templates are used
 * in other contexts, the function template type is used

Each type from the list above from the parameter template is deduced. Before deduction begins, each parameter of the parameter template and the corresponding argument  of the argument template is adjusted as follows:


 * If both and  are reference types before, determine which is more cv-qualified (in all other cases, cv-qualificiations are ignored for partial ordering purposes)
 * If is a reference type, it is replaced by the type referred to
 * If is a reference type, it is replaced by the type referred to
 * If is cv-qualified,  is replaced with cv-unqualified version of itself
 * If is cv-qualified,  is replaced with cv-unqualified version of itself
 * If was transformed from a function parameter pack and  is not a parameter pack, deduction fails

After these adjustments, deduction of from  is done following.

If the argument of the transformed template-1 can be used to deduce the corresponding parameter  of template-2, but not vice versa, then this  is more specialized than  with regards to the type(s) that are deduced by this P/A pair.

If deduction succeeds in both directions, and the original and  were reference types, then additional tests are made:
 * If was lvalue reference and  was rvalue reference, A is considered to be more specialized than P
 * If was more cv-qualified than, A is considered to be more specialized than P

In all other cases, neither template is more specialized than the other with regards to the type(s) deduced by this P/A pair.

After considering every P and A in both directions, if, for each type that was considered,
 * template-1 is at least as specialized as template-2 for all types
 * template-1 is more specialized than template-2 for some types
 * template-2 is not more specialized than template-1 for any types OR is not at least as specialized for any types

Then template-1 is more specialized than template-2. If the conditions above are true after switching template order, than template-2 is more specialized than template-1. Otherwise, neither template is more specialized than the other.

If, after considering all pairs of overloaded templates, there is one that is unambiguously more specialized than all others, that template's specialization is selected, otherwise compilation fails.

In the following examples, the fictitious arguments will be called U1, U2

Partial ordering of a type explicitely specified and a type infered from a deduced type is equivalent. So in the following example the call is ambigous.

Since in a call context considers only parameters for which there are explicit call arguments, some parameters are ignored:

The following actually compiles though in its comment says the result is ambiguous.

The following actually compiles though in its comment says the result is ambiguous.

During template argument deduction within the partial ordering process, template parameters don't require to be matched with arguments, if the argument is not used in any of the types considered for partial ordering

Partial ordering of function templates containing template parameter packs is independent of the number of deduced arguments for those template parameter packs.