首页 > 编程语言 >利用PImpl在C++14中优雅调用C++17方法

利用PImpl在C++14中优雅调用C++17方法

时间:2023-06-05 16:12:06浏览次数:39  
标签:std 14 17 C++ checker wrapper CheckerWrapper

诉求

你的工程由C++14写成,某天你看中了一个功能强大的三方库,一切都好除了该库仅支持C++17编译,对于比较复杂的三方库使用C++14进行重构工作量太大,有没有优雅的办法?

实现

历史总是惊人的相似,为了解决这一问题前人发明了PImpl编程方法用于隐藏class的实现细节,头文件中仅声明抽象class通过一层wrapper完成api的转换。听不懂?上代码。

代码

假设我有一个库必须调用C++17的std::byte作为入参。

class checker:
{
public:
    checker(std::byte b): b_{b} {};
    void show()
    {
        std::cout << std::bitset<8>(std::to_integer<int>(b)) << std::endl;
    }
private:
    std::byte b_;
};

显然C++14无法正常编译,此时引入PImpl方法。
分别定义hpp和cpp文件:

// checker_wrapper.hpp
#pragma once
#include <memory>

class CheckerWrapper
{
public:
    CheckerWrapper(uint8_t b);
    ~CheckerWrapper(); // must, see ref.3
    void show();
private:
    class impl;
    std::unique_ptr<impl> pimpl_;
};


// checker_weapper.cpp
#include "checker_wrapper.hpp"
#include <iostream>
#include <cstddef>
#include <bitset>

class CheckerWrapper::impl
{
public:
    impl(std::byte b): b_{b} {};
    void show()
    {
        std::cout << std::bitset<8>(std::to_integer<int>(b_)) << std::endl;
    }
private:
    std::byte b_;
};

CheckerWrapper::CheckerWrapper(uint8_t b): pimpl_{std::make_unique<impl>(std::byte{b})} {}
CheckerWrapper::~CheckerWrapper() = default;
void CheckerWrapper::show()
{
    pimpl_->show();
}

假设调用工程为test.cpp

#include "checker_wrapper.hpp"

int main()
{
    CheckerWrapper checker{42};
    checker.show();
    return 0;
}

随后将checker_wrapper编译为静态库,配合C++14风格的头文件调用既可。

g++ -std=c++17 -c checker_wrapper.cpp
ar rvs libchecker.a checker_wrapper.o
g++ -std=c++14 test.cpp libchecker.a

参考

PImpl - cppreference.com
c++ - How to create a static library with g++? - Stack Overflow
EffectiveModernCppChinese/item22.md at master · CnTransGroup/EffectiveModernCppChinese · GitHub

标签:std,14,17,C++,checker,wrapper,CheckerWrapper
From: https://www.cnblogs.com/azureology/p/17458055.html

相关文章

  • C++-语法复习
    记录一些刷算法题中的常用C++语法。STL相关向量Vector头文件:#include<vector>初始化:vector<数据类型>变量名(长度,初始化值)赋值初始化:vector<数据类型>变量名={1,2,3,4,5}可以作为数组数组开头:array.begin()数组结尾:array.end()数组大小:array.size()添加元素到......
  • c++中正确使用round()来四舍五入计算
    说明四舍五入的函数参数可以有多种数据类型。不同的数据类型有不同的结果。当他的参数应该是浮点数的时候,结果才是真正的四舍五入。例子/*g++-g-std=c++17./src/basic_demo.cpp-obasic_demo*/#include<iostream>#include<cmath>voidtest_round(){//参数是......
  • C++ 随机数
    ​在许多情况下,需要生成随机数。关于随机数生成器,有两个相关的函数。一个是 rand(),该函数只返回一个伪随机数。生成随机数之前必须先调用 srand() 函数。 下面是一个关于生成随机数的简单实例。实例中使用了 time() 函数来获取系统时间的秒数,通过调用rand()函数来生......
  • Redis系列14:使用List实现消息队列
    Redis系列1:深刻理解高性能Redis的本质Redis系列2:数据持久化提高可用性Redis系列3:高可用之主从架构Redis系列4:高可用之Sentinel(哨兵模式)Redis系列5:深入分析Cluster集群模式追求性能极致:Redis6.0的多线程模型追求性能极致:客户端缓存带来的革命Redis系列8:Bitmap实现亿万级......
  • C++ 定义数字
     我们已经在之前章节的各种实例中定义过数字。下面是一个C++中定义各种类型数字的综合实例:实例#include<iostream>usingnamespacestd; intmain(){//数字定义shorts;inti;longl;floatf;doubled; //数字赋值s=10;i=1000;l=1000000;f=23......
  • visual studio 2010 c++ 创建com组件
    在VisualStudio2010中创建COM组件需要执行以下步骤:1. 打开VisualStudio2010,选择“新建项目”。2. 在弹出的对话框中选择“VisualC++”-->“Win32”-->“Win32项目”,并选择“DLL”作为应用程序类型。3. 单击“下一步”按钮。在下一个页面上,选择“ATL”,然后单击“完......
  • c++实现射线法 点和闭合区域位置关系判断
    c++实现射线法  点和闭合区域位置关系判断#include<iostream>#include<vector>structPoint{doublex;doubley;};structPolygon{std::vector<Point>vertices;};//定义三个点的方向//0-->点p,q,r是共线的//1-->顺时针//2-->......
  • P3750 [六省联考 2017] 分手是祝愿
    简要题意ZeitundRaumtrennendichundmich.时空将你我分开。有一个长度为\(n\)的\(01\)序列。ZYB君在ZBZ爷爷的指引下,重复进行以下操作,直到原序列变成全\(0\)序列:ZBZ爷爷用他智慧的双眼看看这个序列需要ZYB君最多进行几次操作,如果只要进行最多\(k\)次,就......
  • Mysql 主从备份 Last_Errno: 1146 Last_Error: Error executing row event: 错误问题
    本人在做主从备份的时候发现了此问题! 1主数据库是已经把这个表删除了丛数据库也是没有备份这个表但是一直报这个错原因是bin-log日志有这个表 但是没记录到已经把这个表删除了 主从表同步实际从库是根据主库的bin-log二进制的SQL进行执行的 这是Mysql的一个BUG1......
  • SPA17N80C3-ASEMI代理英飞凌MOS管SPA17N80C3
    编辑:llSPA17N80C3-ASEMI代理英飞凌MOS管SPA17N80C3型号:SPA17N80C3品牌:Infineon(英飞凌)封装:TO-220F最大漏源电流:17A漏源击穿电压:800VRDS(ON)Max:0.29Ω引脚数量:3特点新的革命性高压技术全球最佳RDS(上)在TO220中超低栅极电荷周期性雪崩额定值极限dv/dt额定值超低有效......