一、模板函数有模板参数和函数参数,重载调用操作符的类 及 函数指针作为模板实参,其函数参数及函数参数的传参,测试代码如下:

#include <iostream>
using namespace  std;

//key
string s1("Hello");
string s2("World");

//重载了调用操作符的类其对象称为函数对象
class cmp{
public:
    bool operator()(const string& s1, const string& s2)const{
        cout << "bool operator()(const string& s1, const string& s2)const\n";
        return s1 < s2;
    }//类对象为const//成员函数为const//成员函数为const是防止修改类对象
};    

bool compare(const string& s1, const string& s2){
    cout << "bool compare(const string& s1, const string& s2)\n";
    return true;
}

template<typename Compare>     //模板类型
void test( const Compare&c = Compare() ){ //函数参数为const对象引用//默认值为函数对象//
                            //默认值为临时对象,右值,const对象的引用
    cout << "void test( const Compare&c = Compare() )\n";
    c( s1,s2 );
}

int main () 
{
    test<bool(*)(const string&, const string&) >(compare ); //传参
    cout << "--------------------------------------\n"; 
    test<cmp>( );   //默认

    return 0;
}

  模板函数的函数参数,默认为临时对象,应为const对象引用,因为 临时对象为右值

  二、模板类的模板参数 与 构造函数的默认参数

#include <iostream>
using namespace  std;

//key
string s1("Hello");
string s2("World");

//cmp
class cmp{
public:
    bool operator()(const string& s1, const string& s2)const{
        cout << "bool operator()(const string& s1, const string& s2)const\n";
        return s1 < s2;
    }//const
};    

bool compare(const string& s1, const string& s2){
    cout << "bool compare(const string& s1, const string& s2)\n";
    return true;
}

template<typename Compare>     //模板类
struct Test{
    Test( const Compare&c = Compare() ){
        cout << "Test( const Compare&c = Compare() )\n";
        c( s1,s2 );
    }
};

int main () 
{
    Test<bool(*)(const string&, const string&) > t1(compare ); //传参
    cout << "--------------------------------------\n";     
    Test<cmp> t; //默认构造 //不要加小括号!否则就成函数声明了 //Test<cmp> ( );//显式构造

    return 0;
}

  3、非const类对象重载 非const 调用操作符

#include <iostream>
using namespace  std;

class  revision_string{
    string s{"Hello"}; //
public:
    string& operator()(const string& s){//非const函数//可以修改对象
        return this->s = s;
    }
};    

template<typename T>     //模板类
struct Test{
    Test(T &t ){ // 非const引用 
        cout << "Test( T &t )\n";
        cout << t("world");
    }
};

int main () 
{
    revision_string sr;
    Test<revision_string> t(sr ); 

    return 0;
}