zoukankan      html  css  js  c++  java
  • C++中decltype(*)作为模板实参时的隐藏问题

    在函数模板中使用智能指针时,可能会希望根据指针的类型推导出指针引用的对象类型作为模板参数,于是写出以下代码:
    shared_ptr<decltype(*objPtr)>(objPtr);
    一眼看上去似乎是正确的,然而实际上隐藏着一个问题会导致错误,这要从decltype()推断出的类型说起。

    decltype(a)推断出的类型

    • a为变量

      这是最简单的情况,推导出的类型为a的类型T
      int a = 0;
      decltype(a) b; //(int) b
    • a为右值表达式

      同上,推导出的类型为a的类型T
      decltype(2.f) b;   //(float) b
      decltype(b + 1) c;  //(float) c
    • a为左值表达式

      这时decltype推断出的类型是a的引用类型T&;,这也正是造成前文所述问题的根源。
      int b = 0;
      decltype(*(&b)) c; //error: declaration of reference variable 'c' requires an initializer

    回到刚才说的shared_ptr的例子,假设objPtr的类型为Tdecltype(*objPtr)被推断为T&,但shared_ptr的模板实参应为T,所以产生了错误。想要解决这个问题,方法之一是使用std::decay<>

    std::decay<>的使用

    std::decay<>可以把类型的各种修饰(cosnt T, T&, etc.)退化,仅返回基本类型T(或T*T*是不会被退化为T的)。

    std::decay应用于前文的代码,得到:
    shared_ptr<typename std::decay<decltype(*objPtr)>::type>(objPtr);
    注意typename关键字是不能省的,因为编译器无法区分std::decay<decltype(*objPtr)>type成员到底是变量还是类型。


    为了方便理解,本文以函数模板中shared_ptr的使用作为例子;但实际上这个问题可以推广到任何希望以decltype(*)作为模板实参时的场景:如果模板的实参并非T&,就必须通过std::decay<>进行退化处理后再传入。

  • 相关阅读:
    第02组 Beta冲刺 总结
    第02组 Beta冲刺 (5/5)
    第02组 Beta冲刺 (4/5)
    第02组 Beta冲刺 (3/5)
    第02组 Beta冲刺 (2/5)
    第02组 Beta冲刺 (1/5)
    关于IE6中做兼容的那点事。
    一个ajax同步与异步引发的血案。
    浅谈Jquery中的bind(),live(),delegate(),on()绑定事件方式
    浅谈Dictionary用法
  • 原文地址:https://www.cnblogs.com/Excr/p/12516095.html
Copyright © 2011-2022 走看看