第十六章 16.2.5节练习

练习16.42

对下面每个调用,确定T和val的类型:

template <typename T> void g(T&& val);

int i = 0; const int ci = i;

(a) g(i);

(b) g(ci);

(c) g(i * ci);

解答:

#include <iostream>
#include <type_traits>


template <typename T>
void g(T&& val){
  typedef typename std::remove_reference<T>::type A;
  typedef typename std::remove_reference<T&>::type B;
  typedef typename std::remove_reference<T&&>::type C;

  std::cout << std::boolalpha;
  std::cout << "typedefs of int:" << std::endl;
  std::cout << "A: " << std::is_same<const int,A>::value << std::endl;
  std::cout << "B: " << std::is_same<const int,B>::value << std::endl;
  std::cout << "C: " << std::is_same<int,C>::value << std::endl;
}

int i = 0;
const int ci = i;

int main(){
  g(i = ci);
}
使用以上代码进行类型的判别

(a) 类型为int&

(b) 类型为 const int&  int&

(c) 类型为 int&&  const int&&(感谢 隔壁的程序员 同学的勘误)

     关于 隔壁的程序员 提到的引用折叠规则,在 wiki 上有比较详细的介绍。

     这里摘两句出来

    【如果实参是类型A的左值,则模板参数T的类型为A&,形参类型为A&;

    【如果实参是类型A的右值,则模板参数T的类型为A&&,形参类型为A&&。


【2015.05.12】

在评论中也有提到,这里的类型判断不会那么的容易。

今天,重新写了验证程序来验证这三个类型。

先上代码:

#include <iostream>
#include <type_traits>

using namespace std;

static int num;

template <typename T>
void g(T&& val){
  cout << num++ << ":" << endl;
  std::cout << std::boolalpha;
  cout << "T's type is " << typeid(T).name() << endl;
  cout << "T's type is const? " << is_const<T>::value << endl;
  cout << "Is reference? " << is_reference<T&&>::value << endl;
  cout << "Is left reference? " << is_lvalue_reference<T&&>::value << endl;
  cout << "Is right reference? " << is_rvalue_reference<T&&>::value << endl;
}

int i = 0;
const int ci = i;

int main(){
  cout << "i's type is " << typeid(i).name() << endl;
  cout << "ci's type is " << typeid(ci).name() << endl;
  cout << "i * ci's type is " << typeid(i * ci).name() << endl;

  g(i);
  g(ci);
  g(i * ci);
}

C++11中,type_traits头文件中提供了很多对于类型判断的工具,详细跳转到 http://www.cplusplus.com/reference/type_traits/

 i's type is int 

ci's type is int
i * ci's type is int
0:
T's type is int
T's type is const? false
Is reference? true
Is left reference? true
Is right reference? false
1:
T's type is int
T's type is const? false
Is reference? true
Is left reference? true
Is right reference? false
2:
T's type is int
T's type is const? true
Is reference? true
Is left reference? false
Is right reference? true
以上是我在visual studio 2013上运行出来的结果。

结果很清楚了,我在之前的回答中,对于b,c的判断是错误的。(已经在上面更正)

再回头看这题,还是挺有意义的,希望这里的补充能帮到看到我博客的同学。


练习16.43

使用上一题定义的函数,如果我们调用g(i = ci), g的模板参数将是什么?

解答:

这里应该还是i传进去的时候的类型, int&。


练习16.44

使用与第一题中相同的三个调用,如果g的函数参数声明为T(而不是T&&),确定T的类型。如果g的函数参数是const T&呢?

解答:

当声明为T的时候,T的类型为int&。

当声明为const T&的时候,T的类型为int&。


练习16.45

给定下面的模板,如果我们对一个像42这样的字面常量调用g,解释会发生什么?如果我们对一个int类型的变量调用g呢?

template <typename T> void g(T&& val){vector<T> v;}

解答:

当使用字面常量,T将为int。

当使用int变量,T将为int&。编译的时候将会报错,因为没有办法对这种类型进行内存分配,无法创建vector<int&>.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值