使用指针或引用时的模板专业化优先级
我有一个像这样的 Serializer 类:
class Serializer
{
public:
// Func 1 (default)
template <class T>
void Serialize(T* pValue)
{
SerializeInternal(reinterpret_cast<char*>(pValue), sizeof(*pValue));
}
// Func 2 (specialization)
template <>
void Serialize<Serializable>(Serializable* pSerializable)
{
pSerializable->Serialize(*this);
}
protected:
// Implemented by input and output serializers
virtual void SerializeInternal(char* pData, size_t size) = 0;
};
现在我的问题是,当我有继承 Serialized 接口的类时,它们将始终由 Func 1 处理,即使我希望它们由 Func 2 处理(指针或引用并不重要,它们两者行为相同)。似乎 C++ 无法识别 Serialized 接口是继承的,除非您明确指定:
SerializableClass sc; // Inherits Serializable
InputSerializer s; // Inherits Serializer
s.Serialize(&sc); // Func 1 is called >:(
s.Serialize<Serializable>(&sc); // Func 2 is called
现在,只要我忘记在某处添加
,程序当然就会出错,这很漂亮恼人的。
有什么办法解决这个问题吗?
I have a Serializer class like this:
class Serializer
{
public:
// Func 1 (default)
template <class T>
void Serialize(T* pValue)
{
SerializeInternal(reinterpret_cast<char*>(pValue), sizeof(*pValue));
}
// Func 2 (specialization)
template <>
void Serialize<Serializable>(Serializable* pSerializable)
{
pSerializable->Serialize(*this);
}
protected:
// Implemented by input and output serializers
virtual void SerializeInternal(char* pData, size_t size) = 0;
};
Now my problem is when I have classes that inherit the Serializable interface they will always be handled by Func 1, even though I want them to be handled by Func 2 (pointers or references doesn't matter they both behave equally). It seems like C++ doesn't recognize that the Serializable interface is inherited unless you clearly specify that:
SerializableClass sc; // Inherits Serializable
InputSerializer s; // Inherits Serializer
s.Serialize(&sc); // Func 1 is called >:(
s.Serialize<Serializable>(&sc); // Func 2 is called
Now as soon as I forget to add <Serializable>
somewhere the program of course bugs out, which is pretty annoying.
Is there any way around this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是 true。如果您有某个类,则
在推导
T
参数时仅考虑SerializedClass
,而不是Serialized
。如果您需要创建两个函数,一个函数采用任何指针,另一个函数采用指向从 Serialized 派生的任何对象的指针,您可以创建两个重载,并在可能的情况下使用 SFINAE 选择较窄的一个。
如果您不想使用 boost,您可以实现类似于this 的所需功能。
This is true. If you have some class
only
SerializableClass
, notSerializable
, is considered when deducing theT
parameter.If what you need is create two functions, one taking any pointer, the other taking a pointer to anything derived from Serializable, you can create two overloads and use SFINAE to select the narrower one when possible.
If you don't want to use boost, you can implement required functionality akin to this.
使用重载而不是模板专门化!
Use an overload instead of a template specialization!
我找到了一个解释
boost::is_base_of
如何工作的链接:How does ` is_base_of` 工作吗?显然他们使用了一些非常奇特的模板魔法来让它工作。我自己可以“轻松”编写类似的函数。
当你不够聪明,无法自己解决问题时,看看专业人士;)
I found a link explaining how
boost::is_base_of
works: How does `is_base_of` work?Apparently they use some pretty fancy template-fu magic to get it to work. I can "easily" write a similar function myself.
When you're not clever enough to solve it yourself, look at the pros ;)