gpt4 book ai didi

c++ - 强制内部 API 的调用者使用固定大小的类型?

转载 作者:搜寻专家 更新时间:2023-10-31 00:44:17 24 4
gpt4 key购买 nike

我们有一些看起来像这样的代码:

class Serializer
{
public:
template<class Type> void Write(const Type& value)
{
internal_write((byte*)value, sizeof(Type));
}

// some overloads of Write that take care of some tricky type we have defined

private:
// implementation of internal_write
};

正如人们可能猜测的那样,这会将数据写入磁盘。我们有类似的 Read 函数,它们或多或少地将一些字节转换为一个类型。没有它应有的那么健壮,但它确实有效,因为我们在读取时在同一平台上写入——这意味着我们写入的字节与我们需要读取的字节相匹配。

我们现在正在努力支持多个平台。我们在几个地方有这样的代码:

unsigned long trust_me_this_will_be_fine = get_unsigned_long();
a_serializer.Write(trust_me_this_will_be_fine);

这在当前世界中运行良好,但如果我们假设我们要支持的平台之一将 unsigned long 设置为 32 位,而在另一个平台上将其设置为 64 位,我们就会被套牢.

我想更改 Serializer::Write 以仅将明确大小的类型作为参数。我想过这个:

class Serializer
{
public:
void Write(uint32_t value) { ... }
void Write(uint64_t value) { ... }
};

但我认为这并不能真正解决问题,因为在 32 位系统上,unsigned long 会自动转换为 uint32_t 但在 64 位系统上-位系统,它将自动转换为 uint64_t

我在这里真正想要的是让Write(uint32_t) 接受uint32_t类型的参数——这意味着它需要一个显式类型转换。我认为没有直接的方法可以做到这一点——如果我错了,请告诉我。

除此之外,我可以想到两种方法来解决这个问题。

  1. 声明(但不定义)私有(private)版本的 Serializer::Write 用于可以自动转换为我们支持的类型的每种类型。
  2. 不要直接使用 uint32_t,而是使用包含 uint32_t 且只有 uint32_t 的显式构造函数的类。

选项 2 看起来像这样:

class only_uint32
{
public:
uint32_t _value;
explicit only_uint32(uint_32 value) : _value(value) { }
};

class Serializer
{
public:
void Write(only_uint32 value) { ... }
};

然后调用代码如下所示:

unsigned long might_just_work = get_unsigned_long();
a_serializer.Write(static_cast<uint32_t>(might_just_work)); // should work, and be explicitly sized.
a_serializer.Write(might_just_work); // won't compile

我想很多人已经解决了这类问题。有没有我没有想到的首选方法?我的某个想法很糟糕、很棒、可行吗?

P.S.:是的,我知道这是一篇超长的帖子。不过,这是一个有点复杂和详细的问题。

更新:

感谢您的想法和帮助。我想我们会采用这样的解决方案:

class Serializer
{
public:
template<class Type> void Write32(const Type& value)
{
static_assert(sizeof(Type) == 4, "Write32 must be called on a 32-bit value.");
internal_write(reinterpret_cast<byte*>(value), 4);
}
// overloads like Write64 and various tricky types as before.

private:
// implementation of internal_write
};

这是一个成本相当低(就工程时间而言)的解决方案,它成功地将您实际保存的信息推送给调用者,并强制调用者知道他们正在调用什么。

最佳答案

你可以这样做:

template<typename T>
class MyClass {
public:
static_assert(sizeof(T) == sizeof(uint32_t), "Invalid type");
MyClass(T t) : data(t) { }

private:
uint32_t data;
};

或者如果你想接受 uint32_t:

template<typename T>
class MyClass {
public:
static_assert(is_same<T, uint32_t>::value, "Invalid type");
MyClass(T t) : data(t) { }

private:
uint32_t data;
};

关于c++ - 强制内部 API 的调用者使用固定大小的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9107690/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com