诉求
你的工程由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