Like templates and custom templates

Here is the code I don't understand

#include<iostream> using namespace std; template <typename T> T calc(T, T) { cout << "template calc" << endl; } double calc(double, double) { cout << "ordinary calc" << endl; } template <> char calc<char>(char, char) { cout << "template specialisation calc" << endl; } int main() { int ival; double dval; float fd; calc(0, ival); // calls the generic calc(T, T) // the following all call calc(double, double) calc(0.25, dval); calc(0, fd); calc(0, 'J'); calc('I', 'J'); // calls calc(char, char) } 

There are 5 function calls to calculate, so I will call them as 1) - 5) depending on their position.

1) makes sense. 0 is an integer, ival is an integer, it makes sense that calc (T, T) is called. Altho, I feel that my reasoning is that it is wrong. In the end, they both double, so if you call calc (double, double), that also makes sense. Therefore, seek clarification here.

2) there are no drams, both are doubled, cause calc (double, double). Plain.

3) fd is a float. You can either call calc (T, T) or calc (double, double). Because 1) led to a call to calc (T, T), I would assume that this will also be the case here, since we again have one parameter equal to 0, but this calls calc (double, double). So it bothers me, especially the difference between this and 1)

4). My first thought was 0 a valid character, so "J", so it calls calc (char, char). It can call calc (T, T) using the generic integer type. But no, both are wrong, it calls calc (double, double). I am very confused about this. It makes no sense to me.

5) it makes sense, but only if I apply the same logic as for 4), which was not true in 4), so if I saw another example of using templates, I would not be sure which logic to apply .

Look for an explanation of why this program does what it does.

Thanks.

+4
source share
2 answers

First of all, when you write the literal "0" in the source code, it is of type "int". And when you look for which function to call, the compiler chooses the best one. If this is not possible, the compiler will perform some implicit type conversion to make it work.

1) Both 0 and ival are int

2) For double and double, calc (double, double) exactly matches

3) No match was found for int and float, so both are converted to double

4) For int and char, same as 3)

5) For char and char, calc (char, char) exactly matches

+1
source

I suggest you read overload resolution :

The process of selecting the most appropriate overloaded function or operator is called overload resolution.

Suppose f is an overloaded function name. When you call the overloaded function f (), the compiler creates a set of function candidates. This set of functions includes all functions with the name f which can be accessed from the point where you called f (). The compiler may include as an alternative function alternative representation of one of these available functions with the name f to facilitate resolution overloading.

After creating a set of candidate functions, the compiler creates a set of viable functions. This feature set is a subset of the candidate functions. The number of parameters of each viable function is consistent with the number of arguments that you used to call f ().

The compiler selects the best viable function, a function that declares that the C ++ runtime will be used when f () is called, from among many viable functions. The compiler does this implicit conversion sequence. An implicit conversion sequence is a sequence of conversions necessary to convert an argument into a function call of the type of the corresponding parameter in the function declaration. Implicit conversion sequences are ranked; some implicit conversion sequences are better than others. The best viable function is one whose parameters are all either better or equivalent implicit conversion sequences than all other viable functions. The compiler will not allow a program in which the compiler was able to find more than one best viable function.

1, 2, and 5 are all exact matches, so no conversions are required.

To explain 3 and 4, note that your program will not compile if you remove the double, double function. This is because the template argument cannot be inferred for 3 and 4 (since the argument types do not match). Because of this, only the double, double function is considered a candidate function.

+1
source

Source: https://habr.com/ru/post/1443795/


All Articles