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(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::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);

七、转发

template

void flip(F f, T1&& t1, T2&& t2)

{

f(std::forward(t2),std::forward(t1));

}

通过std::forward能传递上述参数的类型。
原文链接: https://www.cnblogs.com/linux-hp/p/5802206.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/239285

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月13日 下午6:07
下一篇 2023年2月13日 下午6:07

相关推荐