Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用指针或引用时的模板专门化优先级_C++_Inheritance_Template Specialization - Fatal编程技术网

C++ 使用指针或引用时的模板专门化优先级

C++ 使用指针或引用时的模板专门化优先级,c++,inheritance,template-specialization,C++,Inheritance,Template Specialization,我有一个序列化程序类,如下所示: class Serializer { public: // Func 1 (default) template <class T> void Serialize(T* pValue) { SerializeInternal(reinterpret_cast<char*>(pValue), sizeof(*pValue)); } // Func 2 (specializati

我有一个序列化程序类,如下所示:

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;
};
类序列化程序
{
公众:
//Func 1(默认值)
模板
无效序列化(T*pValue)
{
序列化内部(重新解释强制转换(pValue),sizeof(*pValue));
}
//职能2(专业化)
模板
无效序列化(可序列化*可序列化)
{
p可序列化->序列化(*此);
}
受保护的:
//由输入和输出序列化程序实现
虚拟内部(char*pData,size\u t size)=0;
};
现在我的问题是,当我有继承可序列化接口的类时,它们将始终由Func 1处理,即使我希望它们由Func 2处理(指针或引用并不重要,它们的行为相同)。似乎C++没有认识到可串行化接口是继承的,除非您明确指定:
SerializableClass sc; // Inherits Serializable
InputSerializer s; // Inherits Serializer

s.Serialize(&sc); // Func 1 is called >:(
s.Serialize<Serializable>(&sc); // Func 2 is called
SerializableClass sc;//继承可序列化的
输入序列化程序s;//继承序列化程序
s、 序列化(&sc);//Func 1被称为>:(
s、 序列化(&sc);//调用Func 2
现在,当我忘记在某个地方添加
时,程序当然会出错,这很烦人


有没有办法解决这个问题?

使用重载而不是模板专用化

似乎C++没有认识到可串行化接口是继承的,除非您明确指定

这是真的。如果你有课的话

class SerializableClass : public Serializable
在推导
T
参数时,仅考虑
SerializableClass
,而不考虑
Serializable

如果您需要创建两个函数,一个取任意指针,另一个取从Serializable派生的任何对象的指针,那么您可以创建两个重载,并在可能的情况下使用SFINAE选择较窄的一个

template <class T>
typename boost::enable_if_c<!boost::is_base_of<Serializable, T>::value, void>::type foo(T*) { ... }

template <class T>
typename boost::enable_if<boost::is_base_of<Serializable, T>, void>::type foo(T*) { ... }
模板
typename boost::enable_if_c::value,void>::type foo(T*){…}
模板
typename boost::enable_if::type foo(T*){…}

如果您不想使用boost,可以实现类似于的必需功能。

我找到了一个链接,解释了
boost::is\u base\u of
的工作原理:

显然,他们使用了一些非常奇特的模板魔法来实现它。我自己可以“轻松”编写类似的函数


当你不够聪明自己解决问题时,看看优点;)

这似乎是一个非常相似的问题:检查它,是的,它确实是同一件事。在那里,Boost功能再次成为解决方案。我想我必须接受没有纯C++ C++解决方案(这也解释了为什么它在那个线程中也不起作用)。在C++0x中,
type\u traits
enable\u(如果
是标准库的一部分)。后者对你自己来说是微不足道的,
的基础,可能更棘手。谢谢,但我不使用Boost,也不打算仅仅为了这个而开始使用它。因此,一个非Boost解决方案(如果可能的话)会很好。@DaedalusAlpha:编写自己的类型特征是相当简单的。无论如何,大多数现代标准库都包含它们——它们是TR1的一部分;如果在C++中已经使用了Boost使用功能,那么它在ISSbaseOf中使用什么?我发现的唯一两个合理的选择是使用依赖于编译器的typeid()进行比较,或者使用非常慢的dynamic_cast进行比较。都不是很好的解决方案。@DaedalusAlpha:请参阅我添加到末尾的链接。我不确定boost是否真的使用了这种方法(这是一种相当粗糙的方法),但这是实现它的一种可能性。谢谢,我刚刚找到了一个类似的(相同的?)实现,我将其作为我自己的答案发布: