おそらく TypeID の使用は避けたいと思います。
#include <iostream>
#include <vector>
#include <typeinfo>
template <class T, class U>
void ListObjects(std::vector<U*> &vec)
{
for (U* obj : vec)
{
if (typeid(*obj) == typeid(T))
{
obj->Print();
std::cout<<"\n";
}
}
}
class Parent
{
public:
Parent() {std::cout<<"Parent Constructed\n";}
virtual ~Parent() {std::cout<<"Parent Destructed\n";}
virtual void Print(){std::cout<<"Parent\n";}
};
class Brother : public Parent
{
public:
Brother(){std::cout<<"Brother Constructed\n";}
virtual ~Brother(){std::cout<<"Brother Destructed\n";}
void Print() override {std::cout<<"Brother\n";}
};
class Sister : public Parent
{
public:
Sister(){std::cout<<"Sister Constructed\n";}
virtual ~Sister(){std::cout<<"Sister Destructed\n";}
void Print() override {std::cout<<"Sister\n";}
};
int main()
{
std::vector<Parent*> Objects;
Objects.push_back(new Parent());
Objects.push_back(new Brother());
Objects.push_back(new Sister());
std::cout<<"\n";
ListObjects<Parent>(Objects);
ListObjects<Brother>(Objects);
ListObjects<Sister>(Objects);
for (Parent* c : Objects)
{
delete c;
}
}
どちらが印刷されますか:
多くのコメントは、あなたが何を望んでいるのかわからないので、TypeID を使用しないように言っています..しかし、あなたが何を望んでいるかを知っていると仮定すると、「typeid は必要ありません」とはどういう意味ですか? :
#include <iostream>
#include <vector>
#include <typeinfo>
template <class T>
void ListObjects(std::vector<T*> &vec)
{
for (T* obj : vec)
{
//TypeID isn't needed here because the virtual call will figure out which class's << operator to call.
//If each class has a print function, it can also figure out which class's print function to call..
//obj->Print(); //works too because each class has a print func.
std::cout<<*obj<<"\n"; //Works because each class has an overloaded << operator.
}
}
class Parent
{
protected:
virtual void Print(std::ostream& os) const {os<<"Parent\n";}
public:
Parent() {std::cout<<"Parent Constructed\n";}
virtual ~Parent() {std::cout<<"Parent Destructed\n";}
friend std::ostream& operator << (std::ostream &os, const Parent &p);
};
std::ostream& operator << (std::ostream &os, const Parent &p)
{
p.Print(os);
return os;
}
class Brother : public Parent
{
protected:
void Print(std::ostream& os) const override {os<<"Brother\n";}
public:
Brother(){std::cout<<"Brother Constructed\n";}
virtual ~Brother() {std::cout<<"Brother Destructed\n";}
};
class Sister : public Parent
{
protected:
void Print(std::ostream& os) const override {os<<"Sister\n";}
public:
Sister(){std::cout<<"Sister Constructed\n";}
virtual ~Sister(){std::cout<<"Sister Destructed\n";}
};
int main()
{
std::vector<Parent*> Objects;
Objects.push_back(new Parent());
Objects.push_back(new Brother());
Objects.push_back(new Sister());
std::cout<<"\n";
ListObjects(Objects); //NOTICE we all template types are now inferred.
for (Parent* c : Objects)
{
delete c;
}
}
上記の呼び出しは仮想であるため、コードは TypeID を使用するコードと同じように出力され、コードではテンプレートの中かっこに何も入力する必要がないことに注意してください。typeid を使用して比較する必要がなくなったため、推論されます。
代わりにテンプレートをパラメーターとして前のコードを要求したため、次のようになります。
template <class T, class U>
void ListObjects(std::vector<U*> &vec)
{
for (U* obj : vec)
{
if (typeid(*obj) == typeid(T))
{
obj->Print();
std::cout<<"\n";
}
}
}
次のようになります。
template<typename T>
void ListObjects(std::vector<T*> &vec, const std::type_info &type)
{
for (T* obj : vec)
{
if (typeid(*obj) == type)
{
std::cout<<*obj<<"\n";
}
}
}
次のように使用します。ListObjects(Objects, typeid(Child));
繰り返しますが、これらはすべてまったく同じ結果になります。それはすべて、ニーズ/ユースケースに依存します。あなたが「何」を達成したいのか、正確にはわかりません。これらはあなたを助けるはずです。