Abstract:C ++ proverbs: the timing of declaring a non-member function explains why only non-memberfunctions (non-member c ++ proverbs: the timing of declaring a non-member function explains why only non-member functions (non-member function) is suitable for implicit type conversions (implicit type conversion) applied to all arguments (real parameters ), it also serves as an example to use the operator * function of a rational class. I recommend that you familiarize yourself with the example before reading this article, because this article is intended for C ++ proverbs: the example in the declaration of the opportunity for a non-member function is an extension discussion of templated rational and operator:
Template <typename T> Class rational { Public: Rational (const T & Numerator = 0, // See C ++ proverbs: Replace the passed value with the passed reference to const. For why Params Const T & Denominator = 1); // are now passed by referenceConst t numerator () const; // See C ++ proverbs: avoid returning the handle to the internal component of an object for why return Const t denominator () const; // values are still passed by value, ... // Item 3 for why they're const }; Template <typename T> Const rational <t> operator * (const rational <t> & LHS, Const rational <t> & RHs) {...} |
Just like in "C ++ proverbs: the time to declare a non-member function", I want to support mixed-mode arithmetic (mixed mode operation ), so we need to make the following code compile. We expect it to work, because we use the same code as the code that can work in item 24. The only difference is that rational and operator * are now templates (templates ):
Rational <int> onehalf (1, 2); // This example is from C ++ proverbs: the time to declare a non-member function. // Snapshot t rational is now a templateRational <int> result = onehalf * 2; // error! Won't compile |
The fact that compilation fails implies that some things are different from non-template versions for templated rational, and they do exist. In C ++ proverbs: declaring a non-member function, the compiler knows what function we want to call (get the operator * of two rationals), but here, the compiler does not know which function we want to call. As an alternative, they try to determine from the template (Template) named operator * to implement (that is, to create) What function. They know that they assume that a function named operator * from the instance gets two rational <t>
Type parameters, but to do this instantiation, they must determine what t is. The problem is that they cannot.
During the deduction t attempt, they will view the type of arguments (real parameter) called by the passed operator. In the current situation, the types are rational <int> (onehalf type) and INT (2 type ). Each parameter is investigated separately.
Using onehalf is simple. The first parameter (parameter) of operator * is declared as the rational <t> type, and the first argument (real parameter) (onehalf) passed into operator * is the rational <int> type, so T must be Int. Unfortunately, deduction for other parameters is not that easy. The second parameter (parameter) of operator * is declared as the int type of rational <t> type, but the second argument (real parameter) (2) of operator * is passed in. In this case, let the compiler determine how
What is t? You may expect them to use the non-explicit Constructor (non-explicit constructor) of rational <int> to convert 2 to a rational <int>, in this way, the T is int, but they do not. They do not do this because implicit type conversion functions (implicit type conversion function) is not considered during the template argument deduction (real parameter deduction of the template) process ). Never. This type of conversion can be used in the function call process. This is correct, but you must know which function exists before you can call a function. To understand this, you must
Function templates (function template) pushes parameter types (parameter type) (so that you can generate appropriate functions for instances ). However, implicit type conversion called by Constructor (constructor) is not considered during template argument deduction (real parameter deduction of template) (implicit type conversion ). The "C ++ proverbs: Timing of declaring a non-member function" does not include templates (templates). Therefore, the template argument deduction (real parameter deduction of templates) is not a problem.
C ++ template, which is the main problem.
In a template class (Template Class), a friend Declaration (youyuan Declaration) can refer to a specific function. We can use this to actually get the template argument deduction (real parameter deduction of the template) the challenging compiler. This means that the class rational <t> can be declared as a friend function operator * for rational <t> *. Class templates (class template) does not rely on the template argument deduction (template real parameter deduction) (this process only applies
Function templates (function template), so t is always known when class rational is instantiated. Make it easy to declare an appropriate operator * as a friend of rational <t> class.
Original post address: http://c.itwaka.com/basic1/39517.html