C++ primer->16.2 模板实参推断

一、类型转换与模板类型参数

  1、如果一个函数形参的类型使用了模板类型参数,那么它采用特殊的初始化规则。只有很有限的几种类型转换会自动地应用于这些实参。

    ①、顶层const无论是在形参中还是在实参中,都会被忽略

    ②、const转换:可以将一个非const对象的引用(或指针)传递给一个const的引用(或指针)形参。

    ③、数组或函数指针转换:如果函数形参不是引用类型,则可以将对数组或函数类型的实参应用于正常的指针转换。

    如下程序所示:

 1 template<typename T> T fobj(T,T);//实参被拷贝
 2 template<typaname T> T freb(const T&, const T&);//const引用
 3
 4 std::string s1("a value");
 5 const string s2("another value");
 6 fobj(s1,s2);//fobj(string,string);顶层const被忽略
 7 freb(s1,s2);//fobj(const string&, const string&) 非const转换为const
 8
 9 int a[10],b[42];
10 fobj(a,b);//将调用fobj(int*, int*);
11 fref(a,b);//错误 数组类型不匹配

二、函数模板显示实参

  1、在某些情况下,编译器无法推断出模板实参的类型。返回类型就是典型例子,当返回类型与参数列表中任何类型都不相同时,这种情况最常见。在这种情况下,我们显示指定模板实参。

  我们可以定义表示返回类型的第三个模板实参,从而允许用户控制返回类型:

1 template <typename T1, typename T2, typename T3>
2     T1 sum(T2,T3);

  调用时显示指定返回类型:auto val3 = sum<long long>(i,lng);

三、我们可以通过第二种方式来设置返回类型-尾置返回类型,这样就可以减少用户额外负担。

template <typename It>
auto fcn(It beg, It end) -> decltype(*beg)
{
    return *beg;
}

  此例中,解引用运算符返回一个左值,因此通过decltype推断的类型为beg表示元素类型的引用。因此如果对一个string序列调用fcn,返回类型将是string&;

  3、可以对类型转换的标准库模板。这里我们简单介绍。一个是remove_reference来获得元素的类型。remove_reference<string &>::type将得到string。

四、函数指针和实参推断。。。

五、模板实参推断和引用

  1、如果一个函数模板类型参数的类型是T&,绑定规则告诉我们,只能传递给它一个左值。

  2、如果一个函数模板类型参数的类型是const T&,正常的绑定规则告诉我们可以传递给它任何类型的实参。注:const已经是函数参数类型一个部分。

  3、如果一个函数模板类型参数的类型是T&&,正常绑定规则告诉我们应该传递给它一个右值,其实不尽然,这里存在这两个例外。

    ①:当我们将一个左值传递给函数的右值引用参数,编译器推断出类型参数为实参的左值的引用类型。通常,我们不能定义一个引用的引用。但是,通过类型别名或通过模板类型参数间接定义是可以的。

    ②:如果我们间接创建一个引用的引用,,则这些引用形成了“折叠”。除了右值引用的右值引用会折叠成右值引用,其它都会折叠成左值引用。

  4、通常使用右值引用的函数模板,我们都会进行函数重载。如下

1 template<typename T> void f(T&&);//绑定到非const右值
2 template<typename T> void f(const T&);//左值和const右值

六、std::move

  

template <typename T>
    typename remove_reference<T>::type&& move(T&& t)
    {
        return static_cast< typename remove_reference<T>::type&&>(t);
    }

    T = string,则会被实例化为string&& move(string&& t);

    T = string&,则会被实例化为string&& move(string& t);

七、转发

  

时间: 2024-10-01 05:03:15

C++ primer->16.2 模板实参推断的相关文章

【C++ Primer 第16章】2. 模板实参推断

模板实参推断:对于函数模板,编译器利用调用中的函数实参来确定模板参数,从函数实参来确定模板参数的过程被称为模板实参推断. 类型转换与模板类型参数 与往常一样,顶层const无论在形参中还是在是实参中,都被会忽略. • const转换:可以将一个非const对象的引用(或指针)传递给const的引用(或指针)形参. • 数组或函数指针转换:一个数组实参可以转换为一个指向其首元素的指针.类似的,一个函数实参可以抓转换一个该函数类型的指针. 1 template <typename T> T fob

模板与泛型编程——模板实参推断

一.模板实参推断 对于函数模板,编译器利用调用中的函数实参来确定其模板参数.从函数实参来确定模板实参的过程被称为模板实参推断.在模板实参推断过程中,编译器使用函数调用中的实参类型来寻找模板实参,用这些模板实参生成的函数与给定的函数调用最为匹配. 1.类型转换与模板类型参数 与非模板函数一样,我们在一次调用中传递给函数模板的实参被用来初始化函数的形参.如果一个函数形参的类型使用了模板类型参数,那么它采用特殊的初始化规则.只有很有限的几种类型转换会自动地应用于这些实参.编译器通常不是对实参进行类型转

C++模板实参推断

1 类型转换与模板实参 1)自动转换的只有:const转换, 数组及函数到指针的转换 注:不同大小相同元素类型是不同的类型 2)相同模板参数名对应的实参类型必须相同 3)不同模板参数名对应的实参类型可以不同,但必须兼容 2 函数模板的返回值问题 函数模板只会对函数参数列表的类型进行推断不会对返回值推断 解决方法: 1) 显示模板参数 注: 显示指定了模板类型参数在类型转换上和普通函数参数一样 template <typename T1, typename T2, typename T3> T1

C++学习笔记(4)----模板实参推断

1. 如图所示代码,模板函数 compare(const T&, const T&) 要求两个参数类型要一样. compare("bye","dad") 调用,将模板参数推断为 const char[4] (因为还有一个 NULL 字符串结尾),而且两个参数都为 const char[4],所以可以正常实例化模板函数. 而 compare("hi","world") 调用,将两个模板参数本别推断为 const

第16章 模板与泛型编程

16.1.1函数模板 //template parameter list template<typename T1,typename T2> int compare(const T1& v1, const T2&v2) { if (v1 < v2) return -1; if (v2 < v1) return 1; return 0; } When we call a function template, the compiler (ordinarily) uses

[014]模板-模板实参推导

对于函数模板,编译器利用调用中的函数实参来确定其函数模板,从函数实参来确定模板实参的过程就被叫做是模板实参推导. 比如: 1 #include<iostream> 2 #include<string> 3 using namespace std; 4 5 template <class T> 6 int compare(const T &v1, const T &v2) { 7 if (v1 > v2) { 8 cout << &quo

16.1——模板与泛型编程

16 模板定义 16.1 定义函数模板 1 #include<iostream> 2 using namespace std; 3 template<typename T> 4 int compare(const T &v1,const T &v2) 5 { 6 if(v1<v2) 7 return -1; 8 if(v1>v2) 9 return 1; 10 return 0; 11 } 12 int main() 13 { 14 int a,b; 1

如何验证模版实参推断结果

在<C++ Primer>第五版中,关于模版实参推断,讲述了如下内容 1.类型转换与模版类型参数 2.函数模版的显式实参 3.尾置返回类型 4.类型转换 5.函数指针和实参推断 6.模版参数推断和引用 书中留给大家一些习题,要求大家给出模版参数的推断类型,参见16.2.5节练习.问题是如何验证我们的答案是否正确,我在这里给出一段代码,抛砖引玉! template <typename T> void g(T&& val) { if(is_lvalue_referenc

如何获得C++模版实参推断结果

在<C++ Primer>第五版中,关于模版实参推断,讲述了如下内容 1.类型转换与模版类型参数 2.函数模版的显式实参 3.尾置返回类型 4.类型转换 5.函数指针和实参推断 6.模版参数推断和引用 书中留给大家一些习题,要求大家给出模版参数的推断类型,参见16.2.5节练习.问题是如何验证我们的答案是否正确,我在这里给出一段代码,抛砖引玉! <span style="font-size:14px;">template <typename T> v