c++ template笔记(1)模板函数

本文详细解析了C++中函数模板与模板函数重载的使用方法,包括如何定义函数模板、如何使用模板函数,以及如何解决模板参数默认值、返回类型等问题,并通过实例展示了模板函数重载的技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二、function template不能有默认模板参数,如下则报错

 

int c = 10;//定义一个变量,用于作为T2的默认值

 

//b设定一个默认参数

template < typename T1, typename T2 >

inline T1 max( const T1& a, const T2& b = c )

{

return a < b ? b : a;

}

 

int main()

{

//调用时出错,提示无法为T2进行类型推导

max( 4 );

return 0;

}

 

其中第二个参数用了默认参数,结果编译器提示错误“could not deduce template argument for 'T2'”。这点也class template不同,在class template中允许传入默认参数(class template后续讨论)。

 

三、对于上面的程序,不能以引用的(by reference)的方式返回值。如把程序改为

 

template < typename T1, typename T2 >

inline const T1& max( const T1& a, const T2& b )

{

return a < b ? b : a;

}

 

int main()

{

std::cout << max( 4, 5.2 ) << std::endl;

return 0;

}

 

输出是5,但程序是有问题的,因为返回值类型是int,对于5.2(编译器认为是double型),编译器会强制转换为int5(此时编译器会有警告,提示从double转为int会导致精度的丢失),并用一个int的临时变量来保存返回的结果,最后将这个临时变量返回。我们知道,当函数的作用域结束时,临时变量会被释放掉,因此返回临时变量的引用或者地址(其实道理一样),都是不明智的,因此上面的程序只能返回T1,而不能返回T1&

当然,如果类型相同,如max( 4, 5)都为整型,则不会出现上面的问题,但此时何不把T1T2定义为相同的类型呢?如 inline const T& max( const T& a, const T& b )。实际上,为了保持代码的简单,推荐的做法便是尽量将函数模板的类型定义为相同的,即【单一类型】。

 

四、或许已经有人想到,其实可以再定义一个类型作为函数模板的返回类型,如下的RT

template<typename T1, typename T2, typename RT>

inline const RT& max( const T1& a, const T2& b );

 

但是请先明白,函数模板对于参数的推导,仅仅限于传入的调用参数,对于返回值的类型,推导机制并不会对其与返回值进行匹配,因此编译器无法推导出RT

怎么办呢?既然编译器无法自己推导,那我们可以明确指定啊!因此对于上面的函数模板,我们可以使用这种方法调用max<int,double,double>(4, 5.2);<>中的第三个类型对应于返回类型RT

 

为了少写一点参数,其实可以对模板中声明的类型顺序改变一下,因为函数模板的调用参数(call parameters)还是可以利用编译器自己去推导的,改后的声明如下

template<typename RT, typename T1, typename T2>

inline const RT& max( const T1& a, const T2& b );

调用方式max<double>(4, 5.2);//只需声明函数的返回类型是double

1.定义函数模板

template <typename T>
inline T const& max (T const& a, T const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

2.使用模板函数

#include <iostream>
#include <string>
#include "max.hpp"

int main()
{
    int i = 42;
    std::cout << "max(7,i):   " << ::max(7,i) << std::endl;

    double f1 = 3.4;
    double f2 = -6.7;
    std::cout << "max(f1,f2): " << ::max(f1,f2) << std::endl;

    std::string s1 = "mathematics";
    std::string s2 = "math";
    std::cout << "max(s1,s2): " << ::max(s1,s2) << std::endl;
}

输出结果

3.确定返回的参数

    ::max<double>(1,2); //ok
    //::max(1,1.2);//wrong
    ::max(static_cast<double>(4),4.1);//ok

若两个参数不正确,或者不支持模板定义的特性,编译时则会出错

4.多个模板参数

template <typename T1,typename T2>
inline T1 const& max (T1 const& a, T2 const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

示例

double i = 42.1;
std::cout << "max(7,i):   " << ::max(7,i) << std::endl;

返回值是T1,所以返回是int类型,结果是42,出错了

定义3个参数,第3个参数用于表示返回值类型

template <typename T1,typename T2,typename T3>
inline T3 const& max (T1 const& a, T2 const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

测试

double i = 42.1;
std::cout << "max(7,i):   " << ::max<int,double,double>(7,i) << std::endl;

返回正确的42.1

5.模板函数重载

// maximum of two int values
inline int const& max (int const& a, int const& b) 
{
    return  a < b ? b : a;
}

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b ? b : a;
}

// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
    return ::max (::max(a,b), c);
}

int main()
{
    ::max(7, 42, 68);     // calls the template for three arguments
    ::max(7.0, 42.0);     // calls max<double> (by argument deduction)
    ::max('a', 'b');      // calls max<char> (by argument deduction)
    ::max(7, 42);         // calls the nontemplate for two ints
    ::max<>(7, 42);       // calls max<int> (by argument deduction)
    ::max<double>(7, 42); // calls max<double> (no argument deduction)
    ::max('a', 42.7);     // calls the nontemplate for two ints
}

特别注意::max<>(7, 42);这句的写法 
注意:自动类型转换

::max('a', 42.7); 只适用于常规函数,'a’会完成自动类型转换

6.字符串重载的例子

#include <iostream>
#include <cstring>
#include <string>

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

// maximum of two pointers
template <typename T>
inline T* const& max (T* const& a, T* const& b)
{
    return  *a < *b  ?  b : a;
}

// maximum of two C-strings
inline char const* const& max (char const* const& a,
                               char const* const& b)
{ 
    return  std::strcmp(a,b) < 0  ?  b : a;
}

int main ()
{
    int a=7;
    int b=42;
    ::max(a,b);      // max() for two values of type int

    std::string s="hey";
    std::string t="you";
    ::max(s,t);      // max() for two values of type std::string

    int* p1 = &b;
    int* p2 = &a;
    ::max(p1,p2);    // max() for two pointers

    char const* s1 = "David";
    char const* s2 = "Nico";
    ::max(s1,s2);    // max() for two C-strings
}

注意每个重载函数必须存在着一定的差异.

7.总是把重载函数定义在调用之前

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b ? b : a;
}

// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
    return max (max(a,b), c);  // uses the template version even for ints
}                              // because the following declaration comes
                               // too late:
// maximum of two int values
inline int const& max (int const& a, int const& b) 
{
    return  a < b ? b : a;
}

3参数的max调用的是2参数模板函数,而非最后定义的max非模板函数

8.std:string和char

#include <string>

// note: reference parameters
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

int main()
{
    std::string s;

    ::max("apple","peach");   // OK: same type
    ::max("apple","tomato");  // ERROR: different types
    ::max("apple",s);         // ERROR: different types
}

“apple”会被转成 char[6]数组,所以比较要求数组维度长度相同,第二条”tomato”与”apple”长度不符合,即出错.

s是std:: string类型,而非char数组,所以也出错

9.以非引用参数方式传递

#include <string>

// note: nonreference parameters
template <typename T>
inline T max (T a, T b)
{
    return  a < b  ?  b : a;
}

int main()
{
    std::string s;

    ::max("apple","peach");   // OK: same type
    ::max("apple","tomato");  // OK: decays to same type
    ::max("apple",s);         // ERROR: different types
}

只有最后类型不符合的编译不通过


1.定义函数模板

template <typename T>
inline T const& max (T const& a, T const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

2.使用模板函数

#include <iostream>
#include <string>
#include "max.hpp"

int main()
{
    int i = 42;
    std::cout << "max(7,i):   " << ::max(7,i) << std::endl;

    double f1 = 3.4;
    double f2 = -6.7;
    std::cout << "max(f1,f2): " << ::max(f1,f2) << std::endl;

    std::string s1 = "mathematics";
    std::string s2 = "math";
    std::cout << "max(s1,s2): " << ::max(s1,s2) << std::endl;
}

输出结果

3.确定返回的参数

    ::max<double>(1,2); //ok
    //::max(1,1.2);//wrong
    ::max(static_cast<double>(4),4.1);//ok

若两个参数不正确,或者不支持模板定义的特性,编译时则会出错

4.多个模板参数

template <typename T1,typename T2>
inline T1 const& max (T1 const& a, T2 const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

示例

double i = 42.1;
std::cout << "max(7,i):   " << ::max(7,i) << std::endl;

返回值是T1,所以返回是int类型,结果是42,出错了

定义3个参数,第3个参数用于表示返回值类型

template <typename T1,typename T2,typename T3>
inline T3 const& max (T1 const& a, T2 const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

测试

double i = 42.1;
std::cout << "max(7,i):   " << ::max<int,double,double>(7,i) << std::endl;

返回正确的42.1

5.模板函数重载

// maximum of two int values
inline int const& max (int const& a, int const& b) 
{
    return  a < b ? b : a;
}

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b ? b : a;
}

// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
    return ::max (::max(a,b), c);
}

int main()
{
    ::max(7, 42, 68);     // calls the template for three arguments
    ::max(7.0, 42.0);     // calls max<double> (by argument deduction)
    ::max('a', 'b');      // calls max<char> (by argument deduction)
    ::max(7, 42);         // calls the nontemplate for two ints
    ::max<>(7, 42);       // calls max<int> (by argument deduction)
    ::max<double>(7, 42); // calls max<double> (no argument deduction)
    ::max('a', 42.7);     // calls the nontemplate for two ints
}

特别注意::max<>(7, 42);这句的写法 
注意:自动类型转换

::max('a', 42.7); 只适用于常规函数,'a’会完成自动类型转换

6.字符串重载的例子

#include <iostream>
#include <cstring>
#include <string>

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

// maximum of two pointers
template <typename T>
inline T* const& max (T* const& a, T* const& b)
{
    return  *a < *b  ?  b : a;
}

// maximum of two C-strings
inline char const* const& max (char const* const& a,
                               char const* const& b)
{ 
    return  std::strcmp(a,b) < 0  ?  b : a;
}

int main ()
{
    int a=7;
    int b=42;
    ::max(a,b);      // max() for two values of type int

    std::string s="hey";
    std::string t="you";
    ::max(s,t);      // max() for two values of type std::string

    int* p1 = &b;
    int* p2 = &a;
    ::max(p1,p2);    // max() for two pointers

    char const* s1 = "David";
    char const* s2 = "Nico";
    ::max(s1,s2);    // max() for two C-strings
}

注意每个重载函数必须存在着一定的差异.

7.总是把重载函数定义在调用之前

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b ? b : a;
}

// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
    return max (max(a,b), c);  // uses the template version even for ints
}                              // because the following declaration comes
                               // too late:
// maximum of two int values
inline int const& max (int const& a, int const& b) 
{
    return  a < b ? b : a;
}

3参数的max调用的是2参数模板函数,而非最后定义的max非模板函数

8.std:string和char

#include <string>

// note: reference parameters
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

int main()
{
    std::string s;

    ::max("apple","peach");   // OK: same type
    ::max("apple","tomato");  // ERROR: different types
    ::max("apple",s);         // ERROR: different types
}

“apple”会被转成 char[6]数组,所以比较要求数组维度长度相同,第二条”tomato”与”apple”长度不符合,即出错.

s是std:: string类型,而非char数组,所以也出错

9.以非引用参数方式传递

#include <string>

// note: nonreference parameters
template <typename T>
inline T max (T a, T b)
{
    return  a < b  ?  b : a;
}

int main()
{
    std::string s;

    ::max("apple","peach");   // OK: same type
    ::max("apple","tomato");  // OK: decays to same type
    ::max("apple",s);         // ERROR: different types
}

只有最后类型不符合的编译不通过




1.定义函数模板

template <typename T>
inline T const& max (T const& a, T const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

2.使用模板函数

#include <iostream>
#include <string>
#include "max.hpp"

int main()
{
    int i = 42;
    std::cout << "max(7,i):   " << ::max(7,i) << std::endl;

    double f1 = 3.4;
    double f2 = -6.7;
    std::cout << "max(f1,f2): " << ::max(f1,f2) << std::endl;

    std::string s1 = "mathematics";
    std::string s2 = "math";
    std::cout << "max(s1,s2): " << ::max(s1,s2) << std::endl;
}

输出结果

3.确定返回的参数

    ::max<double>(1,2); //ok
    //::max(1,1.2);//wrong
    ::max(static_cast<double>(4),4.1);//ok

若两个参数不正确,或者不支持模板定义的特性,编译时则会出错

4.多个模板参数

template <typename T1,typename T2>
inline T1 const& max (T1 const& a, T2 const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

示例

double i = 42.1;
std::cout << "max(7,i):   " << ::max(7,i) << std::endl;

返回值是T1,所以返回是int类型,结果是42,出错了

定义3个参数,第3个参数用于表示返回值类型

template <typename T1,typename T2,typename T3>
inline T3 const& max (T1 const& a, T2 const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

测试

double i = 42.1;
std::cout << "max(7,i):   " << ::max<int,double,double>(7,i) << std::endl;

返回正确的42.1

5.模板函数重载

// maximum of two int values
inline int const& max (int const& a, int const& b) 
{
    return  a < b ? b : a;
}

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b ? b : a;
}

// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
    return ::max (::max(a,b), c);
}

int main()
{
    ::max(7, 42, 68);     // calls the template for three arguments
    ::max(7.0, 42.0);     // calls max<double> (by argument deduction)
    ::max('a', 'b');      // calls max<char> (by argument deduction)
    ::max(7, 42);         // calls the nontemplate for two ints
    ::max<>(7, 42);       // calls max<int> (by argument deduction)
    ::max<double>(7, 42); // calls max<double> (no argument deduction)
    ::max('a', 42.7);     // calls the nontemplate for two ints
}

特别注意::max<>(7, 42);这句的写法 
注意:自动类型转换

::max('a', 42.7); 只适用于常规函数,'a’会完成自动类型转换

6.字符串重载的例子

#include <iostream>
#include <cstring>
#include <string>

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

// maximum of two pointers
template <typename T>
inline T* const& max (T* const& a, T* const& b)
{
    return  *a < *b  ?  b : a;
}

// maximum of two C-strings
inline char const* const& max (char const* const& a,
                               char const* const& b)
{ 
    return  std::strcmp(a,b) < 0  ?  b : a;
}

int main ()
{
    int a=7;
    int b=42;
    ::max(a,b);      // max() for two values of type int

    std::string s="hey";
    std::string t="you";
    ::max(s,t);      // max() for two values of type std::string

    int* p1 = &b;
    int* p2 = &a;
    ::max(p1,p2);    // max() for two pointers

    char const* s1 = "David";
    char const* s2 = "Nico";
    ::max(s1,s2);    // max() for two C-strings
}

注意每个重载函数必须存在着一定的差异.

7.总是把重载函数定义在调用之前

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b ? b : a;
}

// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
    return max (max(a,b), c);  // uses the template version even for ints
}                              // because the following declaration comes
                               // too late:
// maximum of two int values
inline int const& max (int const& a, int const& b) 
{
    return  a < b ? b : a;
}

3参数的max调用的是2参数模板函数,而非最后定义的max非模板函数

8.std:string和char

#include <string>

// note: reference parameters
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

int main()
{
    std::string s;

    ::max("apple","peach");   // OK: same type
    ::max("apple","tomato");  // ERROR: different types
    ::max("apple",s);         // ERROR: different types
}

“apple”会被转成 char[6]数组,所以比较要求数组维度长度相同,第二条”tomato”与”apple”长度不符合,即出错.

s是std:: string类型,而非char数组,所以也出错

9.以非引用参数方式传递

#include <string>

// note: nonreference parameters
template <typename T>
inline T max (T a, T b)
{
    return  a < b  ?  b : a;
}

int main()
{
    std::string s;

    ::max("apple","peach");   // OK: same type
    ::max("apple","tomato");  // OK: decays to same type
    ::max("apple",s);         // ERROR: different types
}

只有最后类型不符合的编译不通过




1.定义函数模板

template <typename T>
inline T const& max (T const& a, T const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

2.使用模板函数

#include <iostream>
#include <string>
#include "max.hpp"

int main()
{
    int i = 42;
    std::cout << "max(7,i):   " << ::max(7,i) << std::endl;

    double f1 = 3.4;
    double f2 = -6.7;
    std::cout << "max(f1,f2): " << ::max(f1,f2) << std::endl;

    std::string s1 = "mathematics";
    std::string s2 = "math";
    std::cout << "max(s1,s2): " << ::max(s1,s2) << std::endl;
}

输出结果

3.确定返回的参数

    ::max<double>(1,2); //ok
    //::max(1,1.2);//wrong
    ::max(static_cast<double>(4),4.1);//ok

若两个参数不正确,或者不支持模板定义的特性,编译时则会出错

4.多个模板参数

template <typename T1,typename T2>
inline T1 const& max (T1 const& a, T2 const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

示例

double i = 42.1;
std::cout << "max(7,i):   " << ::max(7,i) << std::endl;

返回值是T1,所以返回是int类型,结果是42,出错了

定义3个参数,第3个参数用于表示返回值类型

template <typename T1,typename T2,typename T3>
inline T3 const& max (T1 const& a, T2 const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

测试

double i = 42.1;
std::cout << "max(7,i):   " << ::max<int,double,double>(7,i) << std::endl;

返回正确的42.1

5.模板函数重载

// maximum of two int values
inline int const& max (int const& a, int const& b) 
{
    return  a < b ? b : a;
}

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b ? b : a;
}

// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
    return ::max (::max(a,b), c);
}

int main()
{
    ::max(7, 42, 68);     // calls the template for three arguments
    ::max(7.0, 42.0);     // calls max<double> (by argument deduction)
    ::max('a', 'b');      // calls max<char> (by argument deduction)
    ::max(7, 42);         // calls the nontemplate for two ints
    ::max<>(7, 42);       // calls max<int> (by argument deduction)
    ::max<double>(7, 42); // calls max<double> (no argument deduction)
    ::max('a', 42.7);     // calls the nontemplate for two ints
}

特别注意::max<>(7, 42);这句的写法 
注意:自动类型转换

::max('a', 42.7); 只适用于常规函数,'a’会完成自动类型转换

6.字符串重载的例子

#include <iostream>
#include <cstring>
#include <string>

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

// maximum of two pointers
template <typename T>
inline T* const& max (T* const& a, T* const& b)
{
    return  *a < *b  ?  b : a;
}

// maximum of two C-strings
inline char const* const& max (char const* const& a,
                               char const* const& b)
{ 
    return  std::strcmp(a,b) < 0  ?  b : a;
}

int main ()
{
    int a=7;
    int b=42;
    ::max(a,b);      // max() for two values of type int

    std::string s="hey";
    std::string t="you";
    ::max(s,t);      // max() for two values of type std::string

    int* p1 = &b;
    int* p2 = &a;
    ::max(p1,p2);    // max() for two pointers

    char const* s1 = "David";
    char const* s2 = "Nico";
    ::max(s1,s2);    // max() for two C-strings
}

注意每个重载函数必须存在着一定的差异.

7.总是把重载函数定义在调用之前

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b ? b : a;
}

// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
    return max (max(a,b), c);  // uses the template version even for ints
}                              // because the following declaration comes
                               // too late:
// maximum of two int values
inline int const& max (int const& a, int const& b) 
{
    return  a < b ? b : a;
}

3参数的max调用的是2参数模板函数,而非最后定义的max非模板函数

8.std:string和char

#include <string>

// note: reference parameters
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

int main()
{
    std::string s;

    ::max("apple","peach");   // OK: same type
    ::max("apple","tomato");  // ERROR: different types
    ::max("apple",s);         // ERROR: different types
}

“apple”会被转成 char[6]数组,所以比较要求数组维度长度相同,第二条”tomato”与”apple”长度不符合,即出错.

s是std:: string类型,而非char数组,所以也出错

9.以非引用参数方式传递

#include <string>

// note: nonreference parameters
template <typename T>
inline T max (T a, T b)
{
    return  a < b  ?  b : a;
}

int main()
{
    std::string s;

    ::max("apple","peach");   // OK: same type
    ::max("apple","tomato");  // OK: decays to same type
    ::max("apple",s);         // ERROR: different types
}

只有最后类型不符合的编译不通过

1.定义函数模板

template <typename T>
inline T const& max (T const& a, T const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

2.使用模板函数

#include <iostream>
#include <string>
#include "max.hpp"

int main()
{
    int i = 42;
    std::cout << "max(7,i):   " << ::max(7,i) << std::endl;

    double f1 = 3.4;
    double f2 = -6.7;
    std::cout << "max(f1,f2): " << ::max(f1,f2) << std::endl;

    std::string s1 = "mathematics";
    std::string s2 = "math";
    std::cout << "max(s1,s2): " << ::max(s1,s2) << std::endl;
}

输出结果

3.确定返回的参数

    ::max<double>(1,2); //ok
    //::max(1,1.2);//wrong
    ::max(static_cast<double>(4),4.1);//ok

若两个参数不正确,或者不支持模板定义的特性,编译时则会出错

4.多个模板参数

template <typename T1,typename T2>
inline T1 const& max (T1 const& a, T2 const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

示例

double i = 42.1;
std::cout << "max(7,i):   " << ::max(7,i) << std::endl;

返回值是T1,所以返回是int类型,结果是42,出错了

定义3个参数,第3个参数用于表示返回值类型

template <typename T1,typename T2,typename T3>
inline T3 const& max (T1 const& a, T2 const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

测试

double i = 42.1;
std::cout << "max(7,i):   " << ::max<int,double,double>(7,i) << std::endl;

返回正确的42.1

5.模板函数重载

// maximum of two int values
inline int const& max (int const& a, int const& b) 
{
    return  a < b ? b : a;
}

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b ? b : a;
}

// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
    return ::max (::max(a,b), c);
}

int main()
{
    ::max(7, 42, 68);     // calls the template for three arguments
    ::max(7.0, 42.0);     // calls max<double> (by argument deduction)
    ::max('a', 'b');      // calls max<char> (by argument deduction)
    ::max(7, 42);         // calls the nontemplate for two ints
    ::max<>(7, 42);       // calls max<int> (by argument deduction)
    ::max<double>(7, 42); // calls max<double> (no argument deduction)
    ::max('a', 42.7);     // calls the nontemplate for two ints
}

特别注意::max<>(7, 42);这句的写法 
注意:自动类型转换

::max('a', 42.7); 只适用于常规函数,'a’会完成自动类型转换

6.字符串重载的例子

#include <iostream>
#include <cstring>
#include <string>

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

// maximum of two pointers
template <typename T>
inline T* const& max (T* const& a, T* const& b)
{
    return  *a < *b  ?  b : a;
}

// maximum of two C-strings
inline char const* const& max (char const* const& a,
                               char const* const& b)
{ 
    return  std::strcmp(a,b) < 0  ?  b : a;
}

int main ()
{
    int a=7;
    int b=42;
    ::max(a,b);      // max() for two values of type int

    std::string s="hey";
    std::string t="you";
    ::max(s,t);      // max() for two values of type std::string

    int* p1 = &b;
    int* p2 = &a;
    ::max(p1,p2);    // max() for two pointers

    char const* s1 = "David";
    char const* s2 = "Nico";
    ::max(s1,s2);    // max() for two C-strings
}

注意每个重载函数必须存在着一定的差异.

7.总是把重载函数定义在调用之前

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b ? b : a;
}

// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
    return max (max(a,b), c);  // uses the template version even for ints
}                              // because the following declaration comes
                               // too late:
// maximum of two int values
inline int const& max (int const& a, int const& b) 
{
    return  a < b ? b : a;
}

3参数的max调用的是2参数模板函数,而非最后定义的max非模板函数

8.std:string和char

#include <string>

// note: reference parameters
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

int main()
{
    std::string s;

    ::max("apple","peach");   // OK: same type
    ::max("apple","tomato");  // ERROR: different types
    ::max("apple",s);         // ERROR: different types
}

“apple”会被转成 char[6]数组,所以比较要求数组维度长度相同,第二条”tomato”与”apple”长度不符合,即出错.

s是std:: string类型,而非char数组,所以也出错

9.以非引用参数方式传递

#include <string>

// note: nonreference parameters
template <typename T>
inline T max (T a, T b)
{
    return  a < b  ?  b : a;
}

int main()
{
    std::string s;

    ::max("apple","peach");   // OK: same type
    ::max("apple","tomato");  // OK: decays to same type
    ::max("apple",s);         // ERROR: different types
}

只有最后类型不符合的编译不通过




1.定义函数模板

template <typename T>
inline T const& max (T const& a, T const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

2.使用模板函数

#include <iostream>
#include <string>
#include "max.hpp"

int main()
{
    int i = 42;
    std::cout << "max(7,i):   " << ::max(7,i) << std::endl;

    double f1 = 3.4;
    double f2 = -6.7;
    std::cout << "max(f1,f2): " << ::max(f1,f2) << std::endl;

    std::string s1 = "mathematics";
    std::string s2 = "math";
    std::cout << "max(s1,s2): " << ::max(s1,s2) << std::endl;
}

输出结果

3.确定返回的参数

    ::max<double>(1,2); //ok
    //::max(1,1.2);//wrong
    ::max(static_cast<double>(4),4.1);//ok

若两个参数不正确,或者不支持模板定义的特性,编译时则会出错

4.多个模板参数

template <typename T1,typename T2>
inline T1 const& max (T1 const& a, T2 const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

示例

double i = 42.1;
std::cout << "max(7,i):   " << ::max(7,i) << std::endl;

返回值是T1,所以返回是int类型,结果是42,出错了

定义3个参数,第3个参数用于表示返回值类型

template <typename T1,typename T2,typename T3>
inline T3 const& max (T1 const& a, T2 const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

测试

double i = 42.1;
std::cout << "max(7,i):   " << ::max<int,double,double>(7,i) << std::endl;

返回正确的42.1

5.模板函数重载

// maximum of two int values
inline int const& max (int const& a, int const& b) 
{
    return  a < b ? b : a;
}

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b ? b : a;
}

// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
    return ::max (::max(a,b), c);
}

int main()
{
    ::max(7, 42, 68);     // calls the template for three arguments
    ::max(7.0, 42.0);     // calls max<double> (by argument deduction)
    ::max('a', 'b');      // calls max<char> (by argument deduction)
    ::max(7, 42);         // calls the nontemplate for two ints
    ::max<>(7, 42);       // calls max<int> (by argument deduction)
    ::max<double>(7, 42); // calls max<double> (no argument deduction)
    ::max('a', 42.7);     // calls the nontemplate for two ints
}

特别注意::max<>(7, 42);这句的写法 
注意:自动类型转换

::max('a', 42.7); 只适用于常规函数,'a’会完成自动类型转换

6.字符串重载的例子

#include <iostream>
#include <cstring>
#include <string>

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

// maximum of two pointers
template <typename T>
inline T* const& max (T* const& a, T* const& b)
{
    return  *a < *b  ?  b : a;
}

// maximum of two C-strings
inline char const* const& max (char const* const& a,
                               char const* const& b)
{ 
    return  std::strcmp(a,b) < 0  ?  b : a;
}

int main ()
{
    int a=7;
    int b=42;
    ::max(a,b);      // max() for two values of type int

    std::string s="hey";
    std::string t="you";
    ::max(s,t);      // max() for two values of type std::string

    int* p1 = &b;
    int* p2 = &a;
    ::max(p1,p2);    // max() for two pointers

    char const* s1 = "David";
    char const* s2 = "Nico";
    ::max(s1,s2);    // max() for two C-strings
}

注意每个重载函数必须存在着一定的差异.

7.总是把重载函数定义在调用之前

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b ? b : a;
}

// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
    return max (max(a,b), c);  // uses the template version even for ints
}                              // because the following declaration comes
                               // too late:
// maximum of two int values
inline int const& max (int const& a, int const& b) 
{
    return  a < b ? b : a;
}

3参数的max调用的是2参数模板函数,而非最后定义的max非模板函数

8.std:string和char

#include <string>

// note: reference parameters
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

int main()
{
    std::string s;

    ::max("apple","peach");   // OK: same type
    ::max("apple","tomato");  // ERROR: different types
    ::max("apple",s);         // ERROR: different types
}

“apple”会被转成 char[6]数组,所以比较要求数组维度长度相同,第二条”tomato”与”apple”长度不符合,即出错.

s是std:: string类型,而非char数组,所以也出错

9.以非引用参数方式传递

#include <string>

// note: nonreference parameters
template <typename T>
inline T max (T a, T b)
{
    return  a < b  ?  b : a;
}

int main()
{
    std::string s;

    ::max("apple","peach");   // OK: same type
    ::max("apple","tomato");  // OK: decays to same type
    ::max("apple",s);         // ERROR: different types
}

只有最后类型不符合的编译不通过


1.定义函数模板

template <typename T>
inline T const& max (T const& a, T const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

2.使用模板函数

#include <iostream>
#include <string>
#include "max.hpp"

int main()
{
    int i = 42;
    std::cout << "max(7,i):   " << ::max(7,i) << std::endl;

    double f1 = 3.4;
    double f2 = -6.7;
    std::cout << "max(f1,f2): " << ::max(f1,f2) << std::endl;

    std::string s1 = "mathematics";
    std::string s2 = "math";
    std::cout << "max(s1,s2): " << ::max(s1,s2) << std::endl;
}

输出结果

3.确定返回的参数

    ::max<double>(1,2); //ok
    //::max(1,1.2);//wrong
    ::max(static_cast<double>(4),4.1);//ok

若两个参数不正确,或者不支持模板定义的特性,编译时则会出错

4.多个模板参数

template <typename T1,typename T2>
inline T1 const& max (T1 const& a, T2 const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

示例

double i = 42.1;
std::cout << "max(7,i):   " << ::max(7,i) << std::endl;

返回值是T1,所以返回是int类型,结果是42,出错了

定义3个参数,第3个参数用于表示返回值类型

template <typename T1,typename T2,typename T3>
inline T3 const& max (T1 const& a, T2 const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

测试

double i = 42.1;
std::cout << "max(7,i):   " << ::max<int,double,double>(7,i) << std::endl;

返回正确的42.1

5.模板函数重载

// maximum of two int values
inline int const& max (int const& a, int const& b) 
{
    return  a < b ? b : a;
}

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b ? b : a;
}

// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
    return ::max (::max(a,b), c);
}

int main()
{
    ::max(7, 42, 68);     // calls the template for three arguments
    ::max(7.0, 42.0);     // calls max<double> (by argument deduction)
    ::max('a', 'b');      // calls max<char> (by argument deduction)
    ::max(7, 42);         // calls the nontemplate for two ints
    ::max<>(7, 42);       // calls max<int> (by argument deduction)
    ::max<double>(7, 42); // calls max<double> (no argument deduction)
    ::max('a', 42.7);     // calls the nontemplate for two ints
}

特别注意::max<>(7, 42);这句的写法 
注意:自动类型转换

::max('a', 42.7); 只适用于常规函数,'a’会完成自动类型转换

6.字符串重载的例子

#include <iostream>
#include <cstring>
#include <string>

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

// maximum of two pointers
template <typename T>
inline T* const& max (T* const& a, T* const& b)
{
    return  *a < *b  ?  b : a;
}

// maximum of two C-strings
inline char const* const& max (char const* const& a,
                               char const* const& b)
{ 
    return  std::strcmp(a,b) < 0  ?  b : a;
}

int main ()
{
    int a=7;
    int b=42;
    ::max(a,b);      // max() for two values of type int

    std::string s="hey";
    std::string t="you";
    ::max(s,t);      // max() for two values of type std::string

    int* p1 = &b;
    int* p2 = &a;
    ::max(p1,p2);    // max() for two pointers

    char const* s1 = "David";
    char const* s2 = "Nico";
    ::max(s1,s2);    // max() for two C-strings
}

注意每个重载函数必须存在着一定的差异.

7.总是把重载函数定义在调用之前

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b ? b : a;
}

// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
    return max (max(a,b), c);  // uses the template version even for ints
}                              // because the following declaration comes
                               // too late:
// maximum of two int values
inline int const& max (int const& a, int const& b) 
{
    return  a < b ? b : a;
}

3参数的max调用的是2参数模板函数,而非最后定义的max非模板函数

8.std:string和char

#include <string>

// note: reference parameters
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

int main()
{
    std::string s;

    ::max("apple","peach");   // OK: same type
    ::max("apple","tomato");  // ERROR: different types
    ::max("apple",s);         // ERROR: different types
}

“apple”会被转成 char[6]数组,所以比较要求数组维度长度相同,第二条”tomato”与”apple”长度不符合,即出错.

s是std:: string类型,而非char数组,所以也出错

9.以非引用参数方式传递

#include <string>

// note: nonreference parameters
template <typename T>
inline T max (T a, T b)
{
    return  a < b  ?  b : a;
}

int main()
{
    std::string s;

    ::max("apple","peach");   // OK: same type
    ::max("apple","tomato");  // OK: decays to same type
    ::max("apple",s);         // ERROR: different types
}

只有最后类型不符合的编译不通过

1.定义函数模板

template <typename T>
inline T const& max (T const& a, T const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

2.使用模板函数

#include <iostream>
#include <string>
#include "max.hpp"

int main()
{
    int i = 42;
    std::cout << "max(7,i):   " << ::max(7,i) << std::endl;

    double f1 = 3.4;
    double f2 = -6.7;
    std::cout << "max(f1,f2): " << ::max(f1,f2) << std::endl;

    std::string s1 = "mathematics";
    std::string s2 = "math";
    std::cout << "max(s1,s2): " << ::max(s1,s2) << std::endl;
}

输出结果

3.确定返回的参数

    ::max<double>(1,2); //ok
    //::max(1,1.2);//wrong
    ::max(static_cast<double>(4),4.1);//ok

若两个参数不正确,或者不支持模板定义的特性,编译时则会出错

4.多个模板参数

template <typename T1,typename T2>
inline T1 const& max (T1 const& a, T2 const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

示例

double i = 42.1;
std::cout << "max(7,i):   " << ::max(7,i) << std::endl;

返回值是T1,所以返回是int类型,结果是42,出错了

定义3个参数,第3个参数用于表示返回值类型

template <typename T1,typename T2,typename T3>
inline T3 const& max (T1 const& a, T2 const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

测试

double i = 42.1;
std::cout << "max(7,i):   " << ::max<int,double,double>(7,i) << std::endl;

返回正确的42.1

5.模板函数重载

// maximum of two int values
inline int const& max (int const& a, int const& b) 
{
    return  a < b ? b : a;
}

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b ? b : a;
}

// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
    return ::max (::max(a,b), c);
}

int main()
{
    ::max(7, 42, 68);     // calls the template for three arguments
    ::max(7.0, 42.0);     // calls max<double> (by argument deduction)
    ::max('a', 'b');      // calls max<char> (by argument deduction)
    ::max(7, 42);         // calls the nontemplate for two ints
    ::max<>(7, 42);       // calls max<int> (by argument deduction)
    ::max<double>(7, 42); // calls max<double> (no argument deduction)
    ::max('a', 42.7);     // calls the nontemplate for two ints
}

特别注意::max<>(7, 42);这句的写法 
注意:自动类型转换

::max('a', 42.7); 只适用于常规函数,'a’会完成自动类型转换

6.字符串重载的例子

#include <iostream>
#include <cstring>
#include <string>

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

// maximum of two pointers
template <typename T>
inline T* const& max (T* const& a, T* const& b)
{
    return  *a < *b  ?  b : a;
}

// maximum of two C-strings
inline char const* const& max (char const* const& a,
                               char const* const& b)
{ 
    return  std::strcmp(a,b) < 0  ?  b : a;
}

int main ()
{
    int a=7;
    int b=42;
    ::max(a,b);      // max() for two values of type int

    std::string s="hey";
    std::string t="you";
    ::max(s,t);      // max() for two values of type std::string

    int* p1 = &b;
    int* p2 = &a;
    ::max(p1,p2);    // max() for two pointers

    char const* s1 = "David";
    char const* s2 = "Nico";
    ::max(s1,s2);    // max() for two C-strings
}

注意每个重载函数必须存在着一定的差异.

7.总是把重载函数定义在调用之前

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b ? b : a;
}

// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
    return max (max(a,b), c);  // uses the template version even for ints
}                              // because the following declaration comes
                               // too late:
// maximum of two int values
inline int const& max (int const& a, int const& b) 
{
    return  a < b ? b : a;
}

3参数的max调用的是2参数模板函数,而非最后定义的max非模板函数

8.std:string和char

#include <string>

// note: reference parameters
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

int main()
{
    std::string s;

    ::max("apple","peach");   // OK: same type
    ::max("apple","tomato");  // ERROR: different types
    ::max("apple",s);         // ERROR: different types
}

“apple”会被转成 char[6]数组,所以比较要求数组维度长度相同,第二条”tomato”与”apple”长度不符合,即出错.

s是std:: string类型,而非char数组,所以也出错

9.以非引用参数方式传递

#include <string>

// note: nonreference parameters
template <typename T>
inline T max (T a, T b)
{
    return  a < b  ?  b : a;
}

int main()
{
    std::string s;

    ::max("apple","peach");   // OK: same type
    ::max("apple","tomato");  // OK: decays to same type
    ::max("apple",s);         // ERROR: different types
}

只有最后类型不符合的编译不通过

1.定义函数模板

template <typename T>
inline T const& max (T const& a, T const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

2.使用模板函数

#include <iostream>
#include <string>
#include "max.hpp"

int main()
{
    int i = 42;
    std::cout << "max(7,i):   " << ::max(7,i) << std::endl;

    double f1 = 3.4;
    double f2 = -6.7;
    std::cout << "max(f1,f2): " << ::max(f1,f2) << std::endl;

    std::string s1 = "mathematics";
    std::string s2 = "math";
    std::cout << "max(s1,s2): " << ::max(s1,s2) << std::endl;
}

输出结果

3.确定返回的参数

    ::max<double>(1,2); //ok
    //::max(1,1.2);//wrong
    ::max(static_cast<double>(4),4.1);//ok

若两个参数不正确,或者不支持模板定义的特性,编译时则会出错

4.多个模板参数

template <typename T1,typename T2>
inline T1 const& max (T1 const& a, T2 const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

示例

double i = 42.1;
std::cout << "max(7,i):   " << ::max(7,i) << std::endl;

返回值是T1,所以返回是int类型,结果是42,出错了

定义3个参数,第3个参数用于表示返回值类型

template <typename T1,typename T2,typename T3>
inline T3 const& max (T1 const& a, T2 const& b)
{
    // if a < b then use b else use a
    return  a < b ? b : a;
}

测试

double i = 42.1;
std::cout << "max(7,i):   " << ::max<int,double,double>(7,i) << std::endl;

返回正确的42.1

5.模板函数重载

// maximum of two int values
inline int const& max (int const& a, int const& b) 
{
    return  a < b ? b : a;
}

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b ? b : a;
}

// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
    return ::max (::max(a,b), c);
}

int main()
{
    ::max(7, 42, 68);     // calls the template for three arguments
    ::max(7.0, 42.0);     // calls max<double> (by argument deduction)
    ::max('a', 'b');      // calls max<char> (by argument deduction)
    ::max(7, 42);         // calls the nontemplate for two ints
    ::max<>(7, 42);       // calls max<int> (by argument deduction)
    ::max<double>(7, 42); // calls max<double> (no argument deduction)
    ::max('a', 42.7);     // calls the nontemplate for two ints
}

特别注意::max<>(7, 42);这句的写法 
注意:自动类型转换

::max('a', 42.7); 只适用于常规函数,'a’会完成自动类型转换

6.字符串重载的例子

#include <iostream>
#include <cstring>
#include <string>

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

// maximum of two pointers
template <typename T>
inline T* const& max (T* const& a, T* const& b)
{
    return  *a < *b  ?  b : a;
}

// maximum of two C-strings
inline char const* const& max (char const* const& a,
                               char const* const& b)
{ 
    return  std::strcmp(a,b) < 0  ?  b : a;
}

int main ()
{
    int a=7;
    int b=42;
    ::max(a,b);      // max() for two values of type int

    std::string s="hey";
    std::string t="you";
    ::max(s,t);      // max() for two values of type std::string

    int* p1 = &b;
    int* p2 = &a;
    ::max(p1,p2);    // max() for two pointers

    char const* s1 = "David";
    char const* s2 = "Nico";
    ::max(s1,s2);    // max() for two C-strings
}

注意每个重载函数必须存在着一定的差异.

7.总是把重载函数定义在调用之前

// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b ? b : a;
}

// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
    return max (max(a,b), c);  // uses the template version even for ints
}                              // because the following declaration comes
                               // too late:
// maximum of two int values
inline int const& max (int const& a, int const& b) 
{
    return  a < b ? b : a;
}

3参数的max调用的是2参数模板函数,而非最后定义的max非模板函数

8.std:string和char

#include <string>

// note: reference parameters
template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

int main()
{
    std::string s;

    ::max("apple","peach");   // OK: same type
    ::max("apple","tomato");  // ERROR: different types
    ::max("apple",s);         // ERROR: different types
}

“apple”会被转成 char[6]数组,所以比较要求数组维度长度相同,第二条”tomato”与”apple”长度不符合,即出错.

s是std:: string类型,而非char数组,所以也出错

9.以非引用参数方式传递

#include <string>

// note: nonreference parameters
template <typename T>
inline T max (T a, T b)
{
    return  a < b  ?  b : a;
}

int main()
{
    std::string s;

    ::max("apple","peach");   // OK: same type
    ::max("apple","tomato");  // OK: decays to same type
    ::max("apple",s);         // ERROR: different types
}

只有最后类型不符合的编译不通过

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值