存储指向具有模板函数的基对象的指针
Storing a pointer to a base object that has template functions
基于以下代码,如何在"Controller"类中存储指向Base的指针?
template< class Derived >
class Base
{
public:
template < typename T >
void Serialise( T* t )
{
Derived* d = static_cast< Derived* >( this );
d->Serialise( t );
}
};
class Derived : public Base< Derived >
{
public:
template < typename T >
void Serialise( T* t )
{
printf( "serialising to object Tn" );
}
};
因此,如果我有一个Controller类,它将调用Serialize函数并传入要串行化的对象,我最终不得不存储指针及其派生类型,因为它是对象类型的一部分,而我需要的是能够在不知道其实际类型是什么的情况下使用Base类型:
class Controller
{
public:
void DoSerialise();
private:
Base< Derived >* m_myObject; // I want this to just be Base* m_myObject but cant due to template!
};
简短的回答-你不能。
假设template参数不影响Base的接口(即:Derived没有出现在任何函数签名中),则可以有一个非模板基类,并且派生类可以是模板。然而,这根本不符合你目前的模式。
在您的情况下,如果模板参数确实影响了接口(我强烈怀疑在这种情况下确实影响了),那么控制器需要了解Derived才能使用Base,那么为了声明Base,它知道Derived的危害在哪里呢。
评论后编辑:是否确实希望任何派生类能够串行化为任何类型?为什么不拥有从Serialiser
基类派生的类的继承结构,那么Serialise()
就可以接受对类型Serialiser
的引用并丢失模板参数。
你不能那样做。但是Base::Serialize所做的唯一一件事就是调用派生类的Serialize方法。为什么不让它成为纯虚拟的,这样Base就不需要模板参数了?
由于基类的类型取决于派生类的类型,因此您似乎不可能采用特定的方法来解决问题。这意味着基类模板实例化不能表示为单个类型,这对于实现您所采用的方法是必要的。
然而,这似乎是一个乞求访问者模式的问题。访问者模式可以在不进行投射的情况下进行双重调度,这正是您想要的。这里有一个可能的解决方案:
// First declare a base serializable interface that accepts a serializer.
struct ISerializer;
struct ISerializable {
virtual void accept_serializer(ISerializer const &) const = 0;
};
// Now declare a base serializer type that can accept any serializable type.
struct Serializable1;
struct Serializable2;
...
struct ISerializer {
virtual void serialize(Serializable1 const &) = 0;
virtual void serialize(Serializable2 const &) = 0;
...
};
// Then implement your concrete serializable types to accept the serializer and
// invoke it on themselves.
struct Serializable1 : public ISerializable {
void acceptSerializer(ISerializer const &s) const {
s.serialize(*this);
}
};
struct Serializable2 : public ISerializable {
void acceptSerializer(ISerializer const &s) const {
s.serialize(*this);
}
};
// You can actually be a bit more clever to eliminate redundant code:
template<typename DerivedT>
struct SerializableAdapter {
void acceptSerializer(ISerializer const &s) const {
s.serialize(*static_cast<DerivedT const *>(this));
}
};
struct Serializable1 : public SerializableAdapter<Serializable1> {
};
struct Serializable2 : public SerializableAdapter<Serializable2> {
};
// Finally, implement your concrete serializers, including one function for each
// serializable type.
struct Serializer1 : public ISerializer {
void serialize(Serializable1 const &s) const {
...
}
void serialize(Serializable2 const &s) const {
...
}
};
struct Serializer2 : public ISerializer {
void serialize(Serializable1 const &s) const {
...
}
void serialize(Serializable2 const &s) const {
...
}
};
// Now you can store the serializers through the base interface.
struct Controller {
void doSerialize(ISerializable &p_serializable) {
p_serializable.acceptSerializer(*m_serializer)
}
private:
ISerializer *m_serializer;
};
相关文章:
- 如何使用单独文件中的派生类访问友元函数对象
- 当使用透明的std函数对象时,我们还需要写空的尖括号吗
- 有没有办法将重载的类函数绑定到函数对象?
- 将指针传递到成员的指针,从模板参数包到函数对象
- 如何在类模板的成员函数中正确调用函数对象?正在生成 Visual Studio 编译器错误 C2440
- 隐式转换为比较函数对象(函子)用于 std::sort 而不是 std::map?
- C++使用函数对象的线程,如何调用多个析构函数而不是构造函数?
- 如何通过接口将函子分配给函数对象
- 对std::函数对象的调用不匹配,该对象是指向成员函数的指针
- 指向std::invoke中成员函数对象的指针
- 如何成功地将函数对象(或lambda)传递给trackbar回调的第二个参数(void*)
- "std::function"的简单版本:函数对象的生存期?
- C++ 将函数对象作为左值和/或右值传递
- SFINAE 用于具有默认参数的函数对象
- 构造函数对象赋值是否泄漏内存
- 如何发送通过绑定到函数/方法创建的函数对象?
- std::for_each 与函数对象
- 将函数对象传递给 std::function
- 访问执行策略for_each函数对象中的迭代器
- 通过C++函数对象类访问参数