如何处理异质容器中的铸造
How to handle casting in Heterogenous container
我正在尝试使用指向非模板基类的指针来实现异构容器。而派生类是一个模板。
注意:派生类类型在编译时是已知的。注意:容器尺寸是固定的。
第一次尝试:使用帮助程序数组来保存正确类型的整数表示形式。它的大小等于容器的大小。然而,我最终得到了许多if语句。
我的问题与此线程略有相似,但我不知道如何使用 std::type_index。
我试图避免使用Boost::variant和运行时多态性来解决这个问题。
我的问题:有没有更好的方法来处理从基类到派生类的转换?
在我的实际问题中编辑1。 模板类有 16 种不同的类型。
例:
template<typename Color, typename Smell, typename Shape, typename Origin>
class Fruit{};
实现:
class Plant
{ public: std::string sound = "I am jst a plant";};
template <typename T>
class Fruit : public Plant
{public: std::string sound = "I am jst a Fruit!";};
// list of types known at compile time.
struct Apple{ }; // types = 0
struct Orange{ }; // types = 1
struct Banana{ }; // types = 2
template <>
class Fruit<Apple> : public Plant
{public: std::string sound = "I am Apple";};
template <>
class Fruit<Orange> : public Plant
{public: std::string sound = "I am Orange";};
template <>
class Fruit<Banana> : public Plant
{public: std::string sound = "I am Banana";};
template <typename T>
void MakeSound(T fruit)
{
std::cout << fruit->sound << std::endl;
}
int main() {
Plant* Basket[5] = {nullptr};
int types[5] = {0};
Basket[0] = new Fruit<Apple>;
types[0] = 0;
Basket[1] = new Fruit<Orange>;
types[1] = 1;
Basket[2] = new Fruit<Orange>;
types[2] = 1;
Basket[3] = new Fruit<Apple>;
types[3] = 0;
Basket[4] = new Fruit<Apple>;
types[4] = 0;
for (int i = 0; i < 5; ++i)
{
if (types[i] == 0)
{
MakeSound(static_cast<Fruit<Apple> *>(Basket[i]));
}
else if (types[i] == 1)
{
MakeSound(static_cast<Fruit<Orange> *>(Basket[i]));
}
else
{
MakeSound(static_cast<Fruit<Banana> *>(Basket[i]));
}
}
}
我建议使用虚函数来检测派生对象类型的 id;我建议在模板类参数中注册的类型 id(作为sound
(以避免需要Fruit
的专业化。
请:你标记了C++11;所以使用智能指针。
我的意思的一个例子
#include <string>
#include <vector>
#include <memory>
#include <iostream>
struct Plant
{ virtual std::size_t getTypeId () = 0; };
struct Apple
{
static constexpr size_t typeId { 0U };
static std::string const & getSnd ()
{ static std::string sound { "I am Apple" }; return sound; }
};
struct Orange
{
static constexpr size_t typeId { 1U };
static std::string const & getSnd ()
{ static std::string sound { "I am Orange" }; return sound; }
};
struct Banana
{
static constexpr size_t typeId { 2U };
static std::string const & getSnd ()
{ static std::string sound { "I am Banana" }; return sound; }
};
template <typename T>
struct Fruit : public Plant
{
virtual std::size_t getTypeId () override { return T::typeId; }
static std::string const & getSnd () { return T::getSnd(); }
};
template <typename T>
void MakeSound(T fruit)
{ std::cout << fruit->getSnd() << std::endl; }
int main()
{
std::vector<std::unique_ptr<Plant>> bask;
bask.emplace_back(new Fruit<Apple>);
bask.emplace_back(new Fruit<Orange>);
bask.emplace_back(new Fruit<Orange>);
bask.emplace_back(new Fruit<Apple>);
bask.emplace_back(new Fruit<Apple>);
bask.emplace_back(new Fruit<Banana>);
for ( auto const & up : bask)
{
switch ( up->getTypeId() )
{
case 0U:
MakeSound(static_cast<Fruit<Apple> *>(up.get()));
break;
case 1U:
MakeSound(static_cast<Fruit<Orange> *>(up.get()));
break;
case 2U:
MakeSound(static_cast<Fruit<Banana> *>(up.get()));
break;
default:
break;
}
}
}
相关文章:
- 警告处理为错误这里有什么问题
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 使用流处理接收到的数据
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 基于多个条件处理地图中的所有元素
- 如何用数字处理log(0)
- SSL上的`curl_easy_send`和`curl_asy_recv`:如何处理`CURLE_AGAIN`
- 错误处理.将系统错误代码映射到泛型
- 从文本文件中读取时钟时间和事件时间并进行处理
- 在运行时处理类型擦除的数据-如何不重新发明轮子
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 用于矢量处理的多个线程
- 对字符串进行排序时,在c++中处理sort()
- 如何处理linux终端中带有负号(-)的C++中的命令行参数
- 处理除以零会导致<csignal>意外行为
- 是否可以在c++中处理字符串流中的各个元素
- 在简单的外壳中进行批处理处理