c++ - 为什么 `uint64_t` 的模板特化与 Mac 平台上的 `unsigned long` 不匹配?
问题描述
为什么使用 clang++ 在 Mac 平台上编译以下代码段失败?sizeof
unsigned long
anduint64_t
都是8,所以我认为它们是同一类型。那么为什么编译认为Serializer<unsigned long>
是抽象的?
因为我已经定义Serializer<uint64_t>, Serializer<int64_t>, Serializer<uint32_t>, Serializer<int32_t>, Serializer<uint16_t>, Serializer<int16_t>, Serializer<uint8_t>, Serializer<int8_t>
了,有没有办法解决这个问题并避免定义更多类型Serializer<unsigned long>
?
以下是错误消息,clang++ 和 g++ 都给出了类似的结果:
example.cpp:23:31:错误:变量类型“Serializer”是一个抽象类
Serializer<unsigned long> s; ^ example.cpp:6:25: note: unimplemented
'Serializer' 中的纯虚方法 'ToString'
virtual std::string ToString(const T* val) = 0; ^ 1 error generated.
#include <iostream>
#include <vector>
#include <algorithm>
template <typename T>
class Serializer {
virtual std::string ToString(const T* val) = 0;
};
template <>
class Serializer<uint64_t> {
public:
virtual std::string ToString(const int8_t* val) {
return "";
}
};
int main(int argc, const char *argv[])
{
// both of the size is 8 bytes
std::cout << " size of unsigned long:" << sizeof(unsigned long) << " sizeof uint64_t:" << sizeof(uint64_t);
// following compile error happen
Serializer<unsigned long> s; //<------- Error happen here
s.ToString(NULL);
return 0;
}
解决方案
正如所讨论的,通过使用 compile-time-error-method,uint64_t
发现类型是unsigned long long
而不是unsigned long
. 大小是相同的,但它们的名称是不同的,而且每个人都知道编译器对名称非常敏感和严格,这是正确的!
无需更改库或更改用户界面即可解决此问题!
只是在标题之间的一些地方添加如下内容:
template <>
class Serializer<unsigned long> : public Serializer<uint64_t>{};
或者,如果用户无法访问uint64_t
更可能出现的类型:
template <>
class Serializer<unsigned long> : public Serializer<unsigned long long>{};
所以现在它知道,对于unsigned long
专业化(在某种程度上)与Serializer<uint64_t>
已经被特别化的情况相同!
此外,根据您的定义,Serializer
您可能还需要向其添加构造函数,例如:
template <>
class Serializer<unsigned long> : public Serializer<unsigned long long>{
Serializer(...DATA...):Serializer<unsigned long long>(...DATA...){}
};
如果您不知道定义是什么,这可能会有所帮助:
//for values
class Serializer<unsigned long> : public Serializer<unsigned long long>{
template<typename ... Ts>
Serializer(Ts ... Vs):Serializer<unsigned long long>(Vs...){}
};
//for objects
class Serializer<unsigned long> : public Serializer<unsigned long long>{
template<typename ... Ts>
Serializer(const Ts& ... Os):Serializer<unsigned long long>(Os...){}
};
祝你好运!
推荐阅读
- macos - QT 在 macos 上找不到连接的低功耗蓝牙设备
- sql - 这种情况如何完成加入?
- sql - 在spark SQL中查找温度变化1度的开始时间和结束时间
- stripe-payments - 在 Stripe Plan 元数据中保留类型
- ios - 避免在 UITableView 上下拉以关闭 UIModalPresentationStyle.pageSheet 中呈现的模式
- html - SQL Server:修改电子邮件的显示方式
- docker - NextJS 应用程序需要在文件上传到公共文件夹后重建
- arduino - Arduino 异常(9)
- javascript - 我想将一个组件的状态发送到另一个组件来渲染它,没有 Redux 怎么办?
- python - 无法将大小为 47040000 的数组重塑为 (60000,32,32,1) 以用于预训练的神经网络