码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2016-08-24 12:39:48      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:

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

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

七、转发

  

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

标签:

原文地址:http://www.cnblogs.com/linux-hp/p/5802206.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!