私はC++のクラステンプレートの概念を理解していると思っていましたが、私のコードを見れば、もはやそれほど確かではありません。クラステンプレートとその型を扱うC++の方法は何ですか?
:私は、例えば、異なるタイプを使用して、MyChild
のインスタンスとコンテナを持っている私のコードで今すぐ
class MyParent
{
std::string m_Name;
MyParent(std::string Name) : m_Name(Name) { }
virtual const std::type_info& GetType() = 0;
};
template <class T>
class MyChild : public MyParent
{
T m_Var;
const std::type_info& GetType() override
{ return typeid(m_Var); }
};
:私はこのような二つのクラス、非テンプレート親と子としてテンプレートを、持っていると言います
MyParent* p1 = new MyChild<int>("one");
MyParent* p2 = new MyChild<float>("two");
MyParent* p3 = new MyChild<double>("three");
std::vector<MyParent*> v = {p1, p2, p3};
これまでのところ、これは明らかです。私の混乱が始まるところです。私はこのベクトル上で反復する関数を持っているとし、各要素でいくつかのことをする必要があるとします。いくつかの例で私は(私の質問は、コード自体に関するものではありませんが、そのような状況に対処する方法を)作っ:私は一度だけ、このコードブロックを持つことになり、たとえば
Pythonのような他の言語で/* ... */
for(auto* p : v)
{
if(p->GetType() == typeid(int))
{
int val = p->m_Var;
std::list<int> lst = {val, 1, 2, 3};
if(val >= 0)
SomeTemplFuncPositive(v * v, lst); // a template variadic function
else
SomeTemplFuncNegative(v * v * -1, lst);
}
else if(p->GetType() == typeid(float))
{
/* ... now the same block c&p again for float? */
}
else if(p->GetType() == typeid(double))
{
/* ... and again for double?! */
}
}
/* ... */
が、 C++では、float
のコードブロック全体をもう一度コピーし、double
の別の時間をコピーする必要があると思われます。
C++を非難したくありませんそうでなければOKです。私はちょうど疑問に思っています、これは本当に一般的に正しいアプローチですか?調整する必要が-ity
テンプレートに問題はありませんが、オブジェクトには問題はありません。 'typeid'のデザインは醜いです。なぜ多型が存在するのか。 – Stargateur
'if(p-> GetType()== typeid(int))'は手続き型コーディング(および思考)を導入しています。 '* p'のクラスの中の' if'ブロックからすべてのコードを移動してください。必要に応じて 'MyChild'を拡張してください。 –
axiac
子クラスが異なる振る舞いをし、型で分岐する必要があるということは、デザインの欠陥を意味します。あなたは本当に解決しようとしている問題は何ですか?それは、XY問題です。問題を解決するために間違った解決方法を選択しましたが、今はインターネットがどのように続行するかを尋ねる時点まで言語が闘っています。私がこの点に着くたびに、それは常に私をそこに導き出し、(根本的に)私のアプローチを変えて、多くのものを改善した解決策の中で、いくつかの後ろ向きの選択です。ちょうど私の2セント... – rubenvb