首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

存储任意引用的 C++ 包装类,但本身不是类模板

存储任意引用的 C++ 包装类,但本身不是类模板,可以使用 C++ 的模板特化和类型擦除技术来实现。

首先,我们需要定义一个包装类,该类将存储任意类型的引用,但本身不是类模板。我们可以使用 std::any 类型来实现这个功能。

代码语言:cpp
复制
#include <any>

class AnyRefWrapper {
public:
    template<typename T>
    AnyRefWrapper(T& ref) : m_ref(std::ref(ref)) {}

    void* get_address() const {
        return &(std::any_cast<std::reference_wrapper<void>>(m_ref).get());
    }

private:
    std::any m_ref;
};

在上面的代码中,我们使用了 std::any 类型来存储任意类型的引用。我们还定义了一个 get_address() 方法,该方法返回引用的地址。

接下来,我们可以使用这个包装类来存储任意类型的引用。

代码语言:cpp
复制
int main() {
    int a = 42;
    std::string b = "hello";

    AnyRefWrapper wrapper_a(a);
    AnyRefWrapper wrapper_b(b);

    std::cout << "Address of a: "<< wrapper_a.get_address()<< std::endl;
    std::cout << "Address of b: "<< wrapper_b.get_address()<< std::endl;

    return 0;
}

在上面的代码中,我们创建了两个 AnyRefWrapper 对象,一个用于存储 int 类型的引用,另一个用于存储 std::string 类型的引用。我们可以使用 get_address() 方法获取这些引用的地址。

需要注意的是,由于我们使用了 std::any 类型来存储引用,因此在使用 get_address() 方法时需要小心,因为如果 std::any 中存储的不是引用类型,那么 get_address() 方法将返回无效的地址。

总之,我们可以使用 C++ 的模板特化和类型擦除技术来实现一个存储任意引用的 C++ 包装类,但本身不是类模板。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

【C++11】可变参数模板新的类功能lambda包装器--C++

一、可变参数模板 1、基本语法及原理 C++11支持可变参数模板,也就是说支持可变数量参数的函数模板和类模板,可变数目的参数被称为参数包,存在两种参数包:模板参数包,表示零或多个模板参数;函数参数包:表示零或多个函数参数...,在模板参数列表中,class…或typename…指出接下来的参数表示零或多个类型列表;在函数参数列表中,类型名后面跟…指出接下来表示零或多个形参对象列表;函数参数包可以用左值引用或右值引用表示,跟前面普通模板一样...0; } 二、新的类功能 1、默认的移动构造和移动赋值 原来C++类中,有6个默认成员函数:构造函数/析构函数/拷贝构造函数/拷贝赋值重载/取地址重载/const 取地址重载,最后重要的是前4个,后两个用处不大...Args> class function; std::function 是一个类模板,也是一个包装器。...std::function 的实例对象可以包装存储其他的可以调用对象,包括函数指针、仿函数、 lambda 、 bind 表达式等,存储的可调用对象被称为 std::function 的目标。

3200

C++进阶:C++11(列表初始化、右值引用与移动构造移动赋值、可变参数模版...Args、lambda表达式、function包装器)

C++进阶:C++11(列表初始化、右值引用与移动构造移动赋值、可变参数模版…Args、lambda表达式、function包装器) 今天接着进行语法方面知识点的讲解 1.统一的列表初始化 1.1{}初始化...那么如果右值引用本身还是右值,不能被改变,那还怎么进行资源的转移 const 右值 ,右值引用后不能改变 万能引用是 C++11 中引入的一种引用类型,用于实现泛型编程时处理模板类型参数的值类别...模板参数包允许在模板参数列表中接受任意数量的参数,并通过展开(expansion)来处理这些参数。...在C++中,std::function是一个通用的函数包装器,它可以用来存储、复制和调用任何可调用对象,包括函数指针、函数对象、Lambda表达式等。...C++中的function本质是一个类模板,function可以封装他们,目标是统一类型,统一后我们能传给各种容器使用,函数指针的话类型复杂、仿函数的类型不同、Lambda表达式没有类型。

15900
  • 【笔记】C++面向对象高级编程

    返回引用是为了方便接收者按照任意喜欢的形式处理返回值. friend是private的所有者声明的, 声明允许访问private的另一个类/函数...., 本质是指针但是被完全包装为了原本对象的样子 引用必须在声明的时候初始化 引用不允许后期改变值, 一旦定义就无法修改指向 引用和range-for很搭, 可用来轻松修改容器的元素 引用最常用于函数参数上...模板参数的标注类型可以用class也可以用typename, 建议使用typename防止歧义 C++对象模型 不管是复合类还是继承类, 都是从内到外构造, 从外到内析构的....因此我们说多态继承的时候是继承了函数的调用权而不是函数本身的空间 虚指针指向虚函数表, 虚函数表按照目标类中函数的声明顺序对函数地址指针进行排列, 函数指针指向代码段中的函数代码位置 对象的函数调用分为静态绑定和动态绑定两种...但是当对象不是const时, 访问数据的时候就需要拷贝一份然后返回引用以供外部安全修改了. new和delete new和delete本身是表达式, 其本身的行为是无法修改的: new: 先调用operator

    91530

    【C++】C++11新特性——可变参数模版、lambda、包装器

    一、可变参数模版 C语言中有可变函数参数,比如我们熟悉的printf和scanf: C++中有时候模版也需要可变参数,C++11的新特性可变参数模板可以接受可变参数的函数模板和类模板,而C++11...Args...args,这个参数包中可以包含0到任意个模板参数 这里的可变指的是参数类型是任意的,参数个数也是任意的 这意味着我们可以像下面这样使用: template ...lambda表达式的类型没有名称,我们通常无法直接引用它,但可以使用auto关键字来存储lambda表达式的实例。...模板参数说明: Ret: 被调用函数的返回类型 Args…:被调用函数的形参 function包装器也叫作适配器。C++中的function本质是一个类模板,也是一个包装器。...,需要指定类域 非静态成员函数取函数指针时要+&符号,静态成员函数可以不加,但建议还是都加上 上面的包装有错误,你能发现吗?

    19810

    比较分析C++、Java、Python、R语言的面向对象特征,这些特征如何实现的?有什么相同点?

    C++中类本身不是对象,对象是类的实例化; (4)  基于类的模型,还是基于对象或原型的模型?...C++是基于类的模型 对象模型:继承 (1)  类层次结构:采用单根的类层次结构,还是任意的类层次结构? C++采用任意的类层次结构; (2)  继承方式:提供哪些继承方式?...(1)  类属:虚函数 用父类的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数,这种技术可以让父类的指针有“多种形态”; (2)  类属:模板函数 模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式...C++采用的是值模型,可以创建静态对象或栈对象; 但只有通过对象引用或指向对象的指针才能实现面向对象的动态约束行为。...参数传递:通过动态束定机制 类属:通过Self指代对象本身 Python语言不是“纯粹”的面向对象语言: 1)  存在全局变量和全局函数; 2)  main函数不是类的方法; 3)  但Python一切皆对象

    1.7K10

    【Example】C++ 回调函数及 std::function 与 std::bind

    作用是对C++中的可调用对象进行包装,例如普通函数、成员函数、模板函数、静态函数、lambda表达式等。 它的最基本的作用是,简化调用的复杂程度,统一调用的方式。...它与 std::function 不同的是,function 是模板类,bind 是模板函数,而 bind 返回的可调用对象可以直接给 function 进行包装并保存。...为什么要进行“包装”与“转发”呢? 首先,不规范的解释是,function 的作用是包装,它可以包装类成员函数,但却无法生成类成员函数的可调用对象。而 std::bind 则是可以生成。...当用作类成员函数的绑定时,第一个参数仍然是作为类成员的可调用对象引用,第二个参数则是对象的指针,而第三个参数开始对应可调用对象的参数表。...2,到 bind 的参数被复制或移动,而且决不按引用传递,除非包装于 std::ref 或 std::cref 。

    5K30

    【C++】深入剖析C++11新特性

    ---- 九、可变参数模版 C++11的新特性可变参数模板能够让您创建可以接受可变参数的函数模板和类模板,相比C++98/03,类模版和函数模版中只能含固定数量的模版参数,可变模版参数无疑是一个巨大的改进...C++中的function本质是一个类模板,也是一个包装器 那么我们来看看,我们为什么需要function呢?...A)包装器function原型: std::function在头文件 // 类模板原型如下 template function; // undefined template...包装器包装类的成员函数的时候,非静态函数第一个参数需要传类名,在赋值的时候需要带上类域,函数需要取地址,静态函数只需要在赋值的时候需要带上类域(这里建议都取地址,方便记忆)。...在使用包装了类的成员函数的包装器的时候,我们第一个参数也要传一个类对象。

    60340

    SWIG 官方文档第二部分 - 机翻中文人肉修正

    7.3.7 包装参考 包装器引用类似于普通的 C++ 引用,但它是可复制构造和可复制赋值的。可以想象,它们可以用于公共 API。...尽管 SWIG 中没有对 std::reference_wrapper 的特殊支持。如果使用包装器引用,用户将需要编写自己的类型映射,这些类似于普通的 C++ 引用类型映射。...例如,由于 SWIG 需要通过%template显式实例化模板,因此std::is_integral本身不会提供太多内容。但是,使用这种元编程技术的模板函数可能对包装很有用。...这些类型映射覆盖默认类型映射,以便存储底层代理类并将其作为指向 shared_ptr 的指针传递而不是指向基础类型的普通指针。...%shared_ptr 宏引入的唯一真正变化是代理类存储了一个指向 shared_ptr 实例的指针,而不是一个指向该实例的原始指针。

    2.3K20

    【C++】C++11风云再起:语法新纪元,性能新巅峰!

    std::initializer_list std::initializer_list 是C++标准库中的一个类模板,用于表示一组以花括号 {} 括起来的初始值序列。...实现机制 内部通过临时数组存储 直接调用构造函数 修改性 不可修改 支持修改 2.可变模板参数 可变参数模板是C++11引入的一种强大的模板功能,允许模板**接受可变数量的模板参数,它为开发泛型代码提供了很大的灵活性...运算符去计算参数包中参数的个数,也可以使用左值引用和右值引用,与普通模板一样。 语法示例: 计算函数参数包的个数。...混合捕获([=, &x] 或 [&. x]):按值捕获所有外部变量的值,但按引用捕获 x 或 按引用捕获所有外部变量的值,但按值捕获 x 。...包装器 function 在C++中,function 是一个通用的函数包装器,它能够储存、复制和调用任何可调用目标,包括普通函数、Lambda表达式、函数对象以及成员函数。

    5810

    【C++】C++11(lambda、可变参数模板、包装器、线程库)

    新的类功能 默认成员函数 原来C++类中,有6个默认成员函数: 构造函数 析构函数 拷贝构造函数 拷贝赋值重载 取地址重载 const 取地址重载 C++11 新增了两个:移动构造函数和移动赋值运算符重载...可变参数模板 下面是一个基本可变参数的函数模板 // Args是一个模板参数包,args是一个函数形参参数包 // 声明一个参数包Args...args,这个参数包中可以包含0到任意个模板参数。...效率比较结论: 包装器 function包装器 function包装器也叫作适配器。C++中的function本质是一个类模板,也是一个包装器。...包装器不是定义可调用对象,而是包装可调用对象。 现今所学的可调用对象有函数指针、仿函数对象、lambda。但他们有各有缺点: 因此,使用function包装起来,这样方便统一类型。...线程函数的参数是以值拷贝的方式拷贝到线程栈空间中的,因此:即使线程参数为引用类型,在线程中修改后也不能修改外部实参,因为其实际引用的是线程栈中的拷贝,而不是外部实参。

    12610

    【Example】C++ Template (模板)概念讲解及编译避坑

    引用 Microsoft Docs: 模板是 c + + 中的泛型编程的基础。 作为强类型语言,c + + 要求所有变量都具有特定类型,由程序员显式声明或由编译器推断。...总结:模板是 C++ 当中支持参数类型与返回值动态化的工具,使开发人员可以动态自定义函数、类中参数与返回值类型。 模板又分为两种:函数模板 与 类模板。...2,类模板 函数模板很好理解,那么类模板是什么呢? 可以在类模板的内部或外部定义成员函数。 如果在类模板的外部定义成员函数,则会像定义函数模板一样定义它们。...然后:类模板当中非类型形参 这是一个什么东西呢? 1,它是一个常量。 2,它的类型只能是 int 、指针、引用这三种内置类型。 3,调用它的只能是一个常量表达式。 它的使用场景?...而 C++ 每一个变量及对象占用的空间在编译的时候就要被确定! 所以 C++ 当中没有绝对的泛型编程概念。 因此,模板类必须是声明与实现同源(不一定是文件不分离),最合适的写法也就是 hpp 文件。

    79720

    C++11

    ,但结果是报错,因为万能引用的前提,模版参数是需进行推导的,而不是要用来进行实例化的。...改正: ,再加一个模版参数,进行推导是左值引用还是右值引用,而不是用原来进行实例化的模版参数 8 新的类功能 强制生成 默认成员函数 原来C++类中,有6个默认成员函数: 1. 构造函数 2....下面就是一个基本可变参数的函数模板 // Args是一个模板参数包,args是一个函数形参参数包 // 声明一个参数包Args...args,这个参数包中可以包含0到任意个模板参数。...11 包装器function function包装器 function包装器 也叫作适配器。C++中的function本质是一个类模板,也是一个包装器。...一定要加&Plus 有了包装器,如何解决模板的效率低下,实例化多份的问题呢?

    14110

    【C++11】解锁C++11新纪元:深入探索Lambda表达式的奥秘

    可变参数模板 可变参数模板是C++11中引入的一种非常有用的语言特性,它允许函数或类模板接受可变数量的参数。...这一特性极大地增加了模板的灵活性和扩展性,使得开发者可以定义更加通用和灵活的函数或类模板 C++11的新特性可变参数模板能够让您创建可以接受可变参数的函数模板和类模板,相比C++98/03,类模版和函数模版中只能含固定数量的模版参数...,这个参数包中可以包含0到任意个模板参数。...C++中的function本质是一个类模板,也是一个包装器 template T useF(F f, T x) { return f(x); } double...C++11中的lambda表达式和包装器是C++发展史上的一个重要里程碑。

    8410

    【C++】C++11常用特性总结

    但如果是右值的拷贝或赋值呢?因为拷贝构造和拷贝赋值的参数是const左值引用,自然可以接收右值的传参,在函数内部必然还是要进行资源的重新拷贝,那是不是有点太浪费了啊?...,因为他们其实各自有一块空间用来存储右值,但rr2是不能被修改的,因为rr2在引用时带有const属性。...C++觉得C语言的函数指针太恶心了,C++进而就搞出来仿函数对象,仿函数实际是一个重载了operator()的一个类,比如下面进行排序的场景,调用库的sort时,sort函数模板的第三个参数的缺省值就是...C++新引入了可变参数模板的语法,即函数的参数可为一个参数包,这个参数包中可以包含任意个数的函数形参,想打印出参数包中参数的个数,可以通过sizeof…()函数取到参数包中参数的个数。 2....像下面这样命令和动作对应的场景,其实就可以用包装器,让包装器包装lambda,然后把string和包装器对象构成的键值对存储到map里面,建立命令和动作的映射关系。

    82140

    C++11(3)

    可变参数模版 C++11 的新特性可变参数模板能够让您创建可以接受可变参数的函数模板和类模板,相比C++98/03,类模版和函数模版中只能含 固定数量 的模版参数,可变模版参数无疑是一个巨大的改...下面就是一个基本可变参数的函数模板: // Args是一个模板参数包,args是一个函数形参参数包 // 声明一个参数包Args...args,这个参数包中可以包含0到任意个模板参数。...0到任意个模板参数。...包装器 function包装器 function 包装器 也叫作适配器。 C++ 中的 function 本质是一个类模板,也是一个包装器。那么我们来看看,我们为什么需要function 呢?...包装器可以很好的解决上面的问题 std::function在头文件 // 类模板原型如下 template function; // undefined

    6810

    多重收纳(类模板)C++

    为了能够包装不同类型的元素,我们决定用模板类来实现这种盒子,并起名为CBox. 然而,我们注意到CBox、CBox等类虽然定义自相同的模板类,但实际上它们是不相容的类型。...b)如果包装值是非空指针,那么一般来说打印指针值是没有什么价值的,我们更关注的是指针所指向的内容。 我们希望能够对T*这样的模板参数类型定义不同处理方式。...通过进一步学习可以了解到c++支持的"模板偏特化"方法: template class CC { ...... }; template class CC模板类定义适合以原生指针作为模板参数的特化版本     由于定义的成员变量为指针类型,且同一对象被new出来后可能被赋予多个所有者,     为了简化编程,本题不考虑析构函数(使用默认的即可)...就是为了对于特定类型来执行不同的代码,而不是去调用通用模板。

    19030

    模板进阶:特化与编译链接全解析

    [C++] 模版初阶-CSDN博客 非类型模板参数 非类型模板参数,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用,定义方法如下: template<class...示例 假设我们有一个通用的数据存储类模板Data,它可以存储两个不同类型的对象: template class Data { public:...,可以存储任意类型的两个数据。...:调用了全特化模板,因为参数类型既不是指针也不是引用。...因此,Date* const& 的意思是“指向Date对象的常量指针的引用”。这个引用在函数内不会改变其所引用的指针对象,也不能通过引用修改指针本身的指向。 已经特化的类中T表示为什么?

    17810

    【C++】C++11中的常见语法(下)

    C++11 一、可变参数模板 C++11 的新特性可变参数模板能够让我们创建可以接受可变参数的函数模板和类模板,相比 C++98/03 ,类模版和函数模版中只能含固定数量的模版参数,可变模版参数是一个巨大的改进...以下是可变参数模板的语法: // Args是一个模板参数包,args是一个函数形参参数包 // 声明一个参数包Args...args,这个参数包中可以包含0到任意个模板参数。...三、包装器 1. function 包装器 function 包装器 也叫作适配器,C++ 中的 function 本质是一个类模板,也是一个包装器。 要学包装器,首先需要知道包装器包装的是什么?...其实包装器包装的是可调用对象,目前我们学习到的可调用对象有:函数指针、仿函数、lambda,我们要学的包装器就是要包装它们三个中的任意一个。...我们先来看看 function 包装器的语法: // 类模板原型如下 template <class Ret, class...

    11010

    【C++】————C++11

    ,表明变量是局部自动存储类型,但是局部域中定义局部的变量默认就是自动存储类型,所以auto就没什么价值了。...可变参数模板   C++11的新特性可变参数模板能够让您创建可以接受可变参数的函数模板和类模板,相比C++98/03,类模版和函数模版中只能含固定数量的模版参数,可变模版参数无疑是一个巨大的改进。...// Args是一个模板参数包,args是一个函数形参参数包 // 声明一个参数包Args...args,这个参数包中可以包含0到任意个模板参数。...包装器 function包装器   function包装器也叫作适配器。C++中的function本质是一个类模板,也是一个包装器。...bind   std::bind函数定义在头文件中,是一个函数模板,它就像一个函数包装器,接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表。

    6310

    c++模板与泛型编程

    最近复习下c++的模板,在这里简单记录先个人对泛型编程和模板的理解,主要针对模板的目标,原理以及场景做分析,欢迎站内大佬做指导和补充。...泛型编程与模板的设计目标 泛型编程的目标是编写可重用的代码,而在c++中泛型编程的工具就是模板。普通函数参数化值,可以编写不依赖特定值的算法;模板参数化类型,可以编写不依赖特定类型的函数和类。...包装类 包装类的实现方式就比较多种多样了,没有特定的套路,针对不同的问题场景有不同的应用。这里尝试列出标准库中常用的实现供参考,自己编写代码时也可以借鉴这里的思路。...感觉这句话很适合对包装类的描述。 智能指针 利用变量的生存期进行动态对象的管理和释放。...- 场景2:在vector中存储数据的引用。在向vector中正常添加数据时,是对原始数据的复制或移动,包括动态扩容时的复制或移动操作,都会导致无法访问原始数据。

    89720
    领券