为什么以下代码片段在使用clang ++的Mac平台上编译失败?
sizeof
unsigned long
和uint64_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;
}
答案 0 :(得分:2)
如前所述,通过使用编译时错误方法,发现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...){}
};
祝你好运!