1. for a template function defined outside of the class, implicit type conversion is not performed when real parameters are made available: This type of conversion can be performed during the function call process, but before a function can be called, the compiler must know that the function exists, and in order to know it, it must first present the parameter type for the relevant function template. This is a difference between Template C ++ and object-oriented C ++.
Templated the example in Clause 24:
Template <typename T> class rational {public: Rational (const T & Numerator = 0, const T & Denominator = 1); // reference const t numerator () const; const t denominator () const; // pass the value, and it is const ...}; template <typename T> const rational <t> operator * (const rational <t> & LHS, const rational <t> & RHs ){...} // define the function overload operator outside the class. Clause 20 provides detailed description of rational <int> onehalf (1, 2); rational <int> result = onehalf * 2; // error, cannot pass compilation! The specific type of the second parameter cannot be determined, so implicit type conversion cannot be performed.
In this example, the first parameter is an object generated by a template class. You can define this overload function in the template class so that when the first object is made available, the template function can also be implemented. The Compiler learns the type of the second parameter to complete implicit type conversion. Operator * can be declared as a friend function:
Template <typename T> class rational {public: Friend const rational operator * (const rational & LHS, const rational & RHs); // declare as a friend function, but not defined in the class, thus, the connector cannot find the function definition ...}; template <typename T> const rational <t> operator * (const rational <t> & LHS, const rational <t> & RHs) // defines. Cannot connect through! {...}
Here, the same code can be compiled but cannot be connected. There are two solutions:
(1) Put the definition into the class as an inline function:
template<typename T>class Rational{public:friend const Rational operator*(const Rational& lhs, const Rational& rhs){return Rational(lhs.numberator() * rhs.numerator(), lhs.denominator() * rhs.denominator());}...};
(2) declare and define an auxiliary function template outside the class to complete the actual work, and call it using the function template within the class:
Template <typename T> class rational; // declare template <typename T> const rational <t> domultiply (const rational <t> & LHS, const rational <t> & RHs) // many compilers require that the template definition must be in the header file {...} template <typename T> class rational {public: Friend const rational operator * (const rational & LHS, const rational & RHs) {return domultiply (LHS, RHS );}...};