如何在 C++ 中统一连接不同的数据类型

How to uniformly interface different datatypes in C++

假设我有两个不同的框架,它们以不同的方式处理相同的资源:一个框架使用 INT 作为描述符,而另一个框架将资源封装在 class.

如何在这些框架之上设计一个抽象层,实际上将这种差异隐藏在通用接口后面?

选择您要使用的接口,并为另一个提供adapter pattern。您将 class(或数据类型)包装在新的 class 中以更改接口,使其与您的其他 classes 兼容。

或者,您可以查看 facade pattern 以了解更适合您的需求。您创建了一个 "front-end" class,它知道如何接触松散连接的接口并为您与它们交互。我非常喜欢所提供的示例,即拨打客户服务热线,然后将您连接到相应的部门。

您甚至可以将适配器与外观一起使用以简化外观的代码。

如果类型足够相似,您可以将 std::conditional 与一些 SFINAE 一起使用。可以在这里找到一个例子:* https://gitlab.com/sweenish/seeded_prng/blob/master/Random.hpp
代码:

#ifndef THIS___RANDOM_HPP
#define THIS___RANDOM_HPP

#include <algorithm>
#include <array>
#include <cstdint>
#include <functional>
#include <iterator>
#include <limits>
#include <random>
#include <type_traits>

namespace rnd {
template <typename T = std::uint32_t, typename Enable = void>
class Mersenne;

template <typename T>
using AllowForUnsigned = std::enable_if_t<std::is_unsigned_v<T>>;

template <typename T>
class Mersenne<T, AllowForUnsigned<T>>
{
public:
    Mersenne();
    T operator()();

    using result_type = T;
    static constexpr result_type min();
    static constexpr result_type max();

private:
    using Twister = std::conditional_t<sizeof(T) <= 4, std::mt19937, std::mt19937_64>;
    Twister engine_;
};

// Class is implemented here, but these details don't matter for this answer; 
// see the link if interested
#endif

此 class 仅在模板类型为无符号时实例化,并且根据无符号类型的大小,engine_ 的类型将为 32 位或 64 位梅森扭曲器 PRNG。也可以说是使用了适配器模式。默认构造函数之外的许多其他声明都存在,因此 class 仍然适用于 <random> 库。

* 无耻自插