- ベストアンサー
テンプレート関数でコンパイルが通りません
- テンプレート関数XXXで、引数のTYPE型によって、XXX内で呼び出す関数が変わります。
- 明示的にAInfoとBInfoのオーバーロードにする手もあるかもしれませんが、XXXの中で、ここには載せていない大多数の部分は、まったく同じなので、テンプレート関数にするのが筋かなと思っています。
- このコンパイルが通るようにするには、どうすれはよいのでしょうか。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
もしも、AInfo と BInfo が全く関連のない型であれば、 typeid で、クラス名を判別できますが……。 本当なら、オーバーロードが最適だと思います。 それも、この場合なら、XXX をオーバーロードするのではないです。 基本は、 class infoBase { virtual int XXX() { ... いろいろな処理 setData(); ... いろいろな処理 } virtual void setData() = 0; } class AInfo : public infoBase { virtual void setData() { setAdata に相当する処理} } class BInfo : public infoBase { virtual void setData() { setBdata に相当する処理} } こんな感じで、XXX は、「論理的なひとつの関数」 setData は、「それぞれのデータに合わせて仮想化」 というのがシンプルで良いと思います。
その他の回答 (3)
- vipasigaru
- ベストアンサー率38% (16/42)
ごめんなさい。なんか勘違いしてた。NO1は無視してください。 さて、おっしゃるように、それぞれの処理の中で、双方同時に定義されていない関数を呼ぶと コンパイルエラーになります。 解決策は「関数名を同じにすればよい」。 具体的には、次のソースの通りです。 #include <stdio.h> class A{ public: void print(){printf("A\n");}; }; class B{ public: void print(){printf("B\n");}; }; void SetData(A){printf("SetA\n");} void SetData(B){printf("SetB\n");}; template<typename T> int XXX(T& arg){ arg.print(); SetData(arg); return 0; }; int main(void){ A a; B b; XXX(a); XXX(b); return 0; } 同名のメンバ関数を呼び出す、または引数が異なる関数を定義し、呼び出す。 質問者さんが書かれた、SetAData,SetBDataを、SetDataとすればたぶん全てがうまくいきます。
お礼
何度もご回答、どうもありがとうございました。おっしゃるとおり、データセット関数を同じ名前にすればよいのですね。
- ahco_i-o
- ベストアンサー率0% (0/1)
SetAData、SetBDataがどんな関数かよくわかりませんが、 AInfo、 BInfo を 引数とするテンプレート関数 SetXDataを作る もしくは、 AInfo を 引数とするSetXData関数 BInfo を 引数とするSetXData関数 を作る ではだめでしょうか?
お礼
ご回答、どうもありがとうございました。よく考えてみると、おっしゃるようにSetXDataでまとめてしまってよいものでした。ここまで頭がまわらなくて…。
- vipasigaru
- ベストアンサー率38% (16/42)
キーワードは「テンプレートの部分特殊化」 以下、サンプルソースです。 #include <stdio.h> typedef unsigned long long A; typedef unsigned short B; template<typename T> int XXX(T& arg){ printf("ノーマル\n"); return 0; } // 以下、特殊化 template<> int XXX(A& arg){ printf("A\n"); return 0; } template<> int XXX(B& arg){ printf("B\n"); return 0; } int main(void){ A a; B b; int c; XXX(a); XXX(b); XXX(c); return 0; }
お礼
ご回答、どうもありがとうございました。typeidというのがあるのですね。勉強します。データの方を継承クラスにする方法もあるのですね。今回は、AInfo とかBInfo は、中身が異なる小さな構造体なので、ここまではしない方針になりましたが、とても勉強になりました。