专栏首页owentC++ 新特性学习(五) — 引用包装、元编程的类型属性和计算函数对象返回类型

C++ 新特性学习(五) — 引用包装、元编程的类型属性和计算函数对象返回类型

这各部分主要是一些很实用和在一些地方帮助编译器自动推断类型的库和函数 首先是引用包装 类名 template< class T > class std::reference_wrapper; 这个类保存了对一个类实例、(成员)函数(指针) 构造时必须传入所引用的对象或引用对象的右值引用 主要方法有 =号操作符, 用于重新绑定引用对象 类型转换操作符, 用于转换为模板目标类的引用类型 get方法, 用于获取引用的对象 ()操作符, 用于执行引用的函数

同时与其配对的函数有 std::ref 返回std::reference_wrapper,可以视为转换对象为引用 std::cref 返回常量引用对象std::reference_wrapper,可以视为转换对象为引用 例程:

// 和std::function和std::bind函数配合使用
#include <cstdio>
#include <functional>

 void assign(int& l, int r) {
    l = r;
 }
int main() {
    int a = 0, b = 10;
    std::function<void()> func = std::bind(&assign, std::ref(a), b); 
    func();

    printf("a => %d, b => %d\n", a, b);
    return 0;
}

注意:如果不用std::ref包装,即便函数申明需传入引用类型,但是由于绑定变量和函数的参数类型推断是分离的,会导致传值而不是引用 另外有些函数,如 std::ptr_fun, 通过函数指针构造函数对象 std::mem_fun, 通过成员函数指针构造函数对象 std::mem_fun_ref, 通过成员函数指针构造函数对象引用 不推荐使用,因为完全可以用std::bind代替,详细请参见 http://www.owent.net/2012/536.html

然后是 元编程的类型属性

元编程的定义是可以修改自身或其他代码的代码,当然,C++不是动态语言,这个修改可以在编译或执行的时期。 说不清楚,还是上代码吧

#include <cstdio>

template <int N>
struct factorial {
    const static int value = N * factorial<N - 1>::value;
};

template <>
struct factorial<1> {
    const static int value = 1;
};

int main() {
    printf("10! = %d\n", factorial<10>::value);
    return 0;
}

比较有意思吧,这个不是新标准,新C++标准增加了类型属性,什么叫类型属性呢? 就是类型判断,也来一个例子吧,这段代码来自维基百科

#include <type_traits>
// 算法一
template< bool B > struct Algorithm {
    template<class T1, class T2> int do_it (T1 &, T2 &)  { /*...*/ }
};

// 算法二
template<> struct Algorithm<true> {
    template<class T1, class T2> int do_it (T1, T2)  { /*...*/ }
};

// 根据给定的类型选择不同的算法
template<class T1, class T2>
int elaborate (T1 A, T2 B)
{
    // 若 T1 为 int 且 T1 为 float,选用算法二
    // 其它情況选用算法一
    return Algorithm<std::is_integral<T1>::value && std::is_floating_point<T2>::value>::do_it( A, B ) ;
}

最后,是今天最后一项,计算函数对象(仿函数)的返回值类型 主要涉及一个模板函数std::result_of,它使用了decltype并支持函数对象(关于decltype请参见 https://www.owent.net/2011/508.html) std::result_of::type 即是返回类型,比如:

struct foo {
    double operator()(char, int);
};
// 这两个是一样的
std::result_of<foo(char, int)>::type d1 = 10.0;
decltype(foo()('c', 1)) d2 = 10.0;

今天就这样over吧。也许是我还没能把C++用的非常灵活吧,感觉后面的部分不太实用的样子。 还需要继续努力啊

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • RFC821 简单邮件传输协议(SMTP)

    苦叶子
  • 看腻了大佬虐菜,只盼三场势均力敌的小组赛,pick一下?

    截止周二早上(6月26日),2018俄罗斯世界杯64场比赛已战36场,小组赛还有最后三晚12场,分别是C、D、F、E、H、G小组的第三轮。

    用户1569917
  • 在Lion上为XAMPP编译APC

    平时在Mac下使用XAMPP进行开发,最近需要用到APC扩展,从PECL上下载了扩展的源文件,在本地进行了编译安装。下面是安装步骤。

    大江小浪
  • Java做爬虫也很牛

    首先我们封装一个Http请求的工具类,用HttpURLConnection实现,当然你也可以用HttpClient, 或者直接用Jsoup来请求(下面会讲到Js...

    猿天地
  • RFC2964 超文本传输协议(HTTP)状态管理的应用

    苦叶子
  • RFC2861 TCP 拥塞窗口检验

    苦叶子
  • Python常用库整理

    https://pygobject.readthedocs.io/en/latest/#

    爱吃西瓜的番茄酱
  • (码友推荐)2018-07-25 .NET及相关开发资讯速递

    3.多人协同开发如何保证代码质量!看看这篇《理想中的Jenkins+Sonar+Github代码质量管理》

    Rector
  • Spring4+Spring MVC+MyBatis整合思路

    这个很简单,只需要web容器中注册org.springframework.web.context.ContextLoaderListener,并指定spring...

    Java学习
  • kitti数据集 自动驾驶各项指标比赛结果、论文、代码

    http://www.cvlibs.net/datasets/kitti/eval_road.php

    用户1908973

扫码关注云+社区

领取腾讯云代金券