如何在 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>
库。
* 无耻自插
假设我有两个不同的框架,它们以不同的方式处理相同的资源:一个框架使用 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>
库。
* 无耻自插