![](/img/trans.png)
[英]How to store templated objects in an STL container and member function call
[英]How to store templated heterogeneous objects in an STL container
问题是关于在MS Visual C ++ 11中开发的代码,只能访问STL,没有Boost。
有一个包装器模板类,大致有这个标头:
template <typename Payload>
class Wrapper {
Payload p;
std::string src;
Wrapper( std::string, Payload );
Payload get(); // returns payload
void set(Payload); // replaces payload
void operator ()(); // uses payload
}
Payload
可能是任何东西 - 指针,整数,甚至是重物。
后来, Wrapper
需要进入一个容器,比如std::vector
- 但不管它们的具体参数类型如何。 这给我带来了麻烦,因为容器需要同质的元素。
我已经尝试过KennyTM这样的基类建议,但是它给了我一些方法get()
和set()
- 当从向量中使用时需要强制转换 (?)因为元素看起来像一个基类,如果在该答案提出的模式。
为此,您需要使用某种类型的擦除。 从最基本的(提供基本类型,通过指针存储元素到基础)到更高级的解决方案,如boost ::任何你可以选择(我知道你提到没有提升,但你总是可以看看实现) 。 或者,如果有效载荷集是已知的并且相对较小,则可以使用变体方法(类似于boost :: variant),但是对于单次使用可能更难实现。
template<typename Payload>
struct Wrapper;
struct WrapperBase {
std::string src;
WrapperBase( std::string s ):src(s) {}
template<typename Payload>
Payload get() const;
template<typename Payload>
void set(Payload);
virtual void operator ()() = 0; // uses payload
};
template <typename Payload>
struct Wrapper {
Payload payload;
Wrapper( std::string s, Payload p ):WrapperBase(s),payload(p) {}
Payload get() const { return payload; }; // returns payload
void set(Payload p) { payload = p; }; // replaces payload
virtual void operator()() override; // todo
}
template<typename Payload>
Payload WrapperBase::get() const {
Assert(dynamic_cast<Wrapper<Payload> const*>(this));
return static_cast<Wrapper<Payload> const*>(this)->get();
}
template<typename Payload>
void WrapperBase::set(Payload p) {
Assert(dynamic_cast<Wrapper<Payload>*>(this));
static_cast<Wrapper<Payload>*>(this)->set(p);
}
如果WrapperBase
用户想要设置/获取有效负载,则需要知道有效负载的类型。 如果您不知道,可以使用dynamic_cast<Wrapper<Payload>*>
来确定给定的WrapperBase
是否是特定类型。
这没有值语义,因此您需要将智能指针的vector
存储到WrapperBase
而不是实际实例。 std::shared_ptr
或std::unique_ptr
是具有非常不同行为的好候选者。
如果存在有限的Payloads
集,则访问者模式可以起作用。
如果您需要值语义,那么存储实际有效负载的pImpl
模式可以使用手动operator=
来克隆pImpl
。
询问“你持有T
型”是可能的,但通常类似于dynamic_cast
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.