![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
テンプレート関数でコンパイルが通りません
いつもお世話になってます。テンプレート関数XXXで、引数のTYPE型によって、XXX内で呼び出す関数が変わります。以下の例では、eTypeがAならSetADataを呼び、eTypeがBならSetBDataを呼び出します。XXXのもうひとつの引数がテンプレート部です。本当は、rInfoの型(AInfoまたはBInfo)を判別できればeTypeは不要なのですが、判別の仕方がわからないので、eTypeでrInfoの型を伝えるようにしています。
template<typename T> int XXX( T& rInfo, const TYPE& eType )
if( eType == A ){
SetAData( rInfo );
else if( eType == B ){
SetBData( rInfo );
}
// 明示的インスタンス生成
template int XXX<AInfo>( AInfo& rInfo, const TYPE& eType )
template int XXX<BInfo>( Binfo& rInfo, const TYPE& eType )
上記のようにした時、コンパイラはTの部分をAInfoとBInfoの両方で解釈するので、どうしても以下のようなコンパイルエラーが出ます。
---
`int XXX(T&, const TYPE&) [with T = AInfo]':
error: no matching function for call to `SetBData(AInfo&)'
note: candidates are: int SetBData(BInfo&)
`int XXX(T&, const TYPE&) [with T = BInfo]':
error: no matching function for call to `SetAData(BInfo&)'
note: candidates are: int SetAData(AInfo&)
XXXをテンプレート関数でなく、明示的にAInfoとBInfoのオーバーロードにする手もあるかもしれませんが、XXXの中で、ここには載せていない大多数の部分は、まったく同じなので、テンプレート関数にするのが筋かなと思っています。このコンパイルが通るようにするには、どうすれはよいのでしょうか。
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_04.png?5a7ff87)
No.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 は、「それぞれのデータに合わせて仮想化」
というのがシンプルで良いと思います。
ご回答、どうもありがとうございました。typeidというのがあるのですね。勉強します。データの方を継承クラスにする方法もあるのですね。今回は、AInfo とかBInfo は、中身が異なる小さな構造体なので、ここまではしない方針になりましたが、とても勉強になりました。
No.3
- 回答日時:
ごめんなさい。
なんか勘違いしてた。NO1は無視してください。さて、おっしゃるように、それぞれの処理の中で、双方同時に定義されていない関数を呼ぶと
コンパイルエラーになります。
解決策は「関数名を同じにすればよい」。
具体的には、次のソースの通りです。
#include <stdio.h>
class A{
public:
voidprint(){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とすればたぶん全てがうまくいきます。
No.1
- 回答日時:
キーワードは「テンプレートの部分特殊化」
以下、サンプルソースです。
#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;
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- Excel(エクセル) SUMIFSと日付変換 10 2023/04/16 15:38
- その他(プログラミング・Web制作) 十進BASICでの再帰についての質問です。 2 2022/11/18 09:17
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- その他(Microsoft Office) パワークエリの複数ファイルのデータ統合について 3 2022/07/14 17:06
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- その他(パソコン・周辺機器) チャレンジタッチ3 改造 アプリインストールできない 1 2022/07/01 14:43
- Excel(エクセル) excelvbaのwithについて 4 2022/12/19 16:51
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
DWORDの実際の型は何でしょうか
-
long型の定数の末尾にLを付ける...
-
2重定義って??
-
typedef enumの使い方を教えて...
-
構造体の要素すべてに対する四...
-
変数の型を定義しなかった場合...
-
intとINTの違いは?
-
VC6でlong longでエラー?
-
DDVによるメッセージの変更
-
gccのエラー "initialization d...
-
void func( void )について
-
ハンドルされていない例外が発...
-
C言語での方向キー入力判定
-
main()とint main(void)の違い
-
直接アドレス指定のポインタの...
-
64bit → 32bit型へのキャスト
-
enumについて
-
HINSTANCEの型
-
クラス間の変数について
-
C++,ヘッダファイルのエラー
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
DWORDの実際の型は何でしょうか
-
long型の定数の末尾にLを付ける...
-
2重定義って??
-
typedef enumの使い方を教えて...
-
visualstudio C# テキストボッ...
-
C++のfor文について
-
関数の実体定義にヘッダファイ...
-
構造体の要素すべてに対する四...
-
ハンドルされていない例外が発...
-
C++でboolにintの値を代入する...
-
変数の型を定義しなかった場合...
-
intとINTの違いは?
-
main.c:7:43: warning: implici...
-
void func( void )について
-
C言語 宣言した変数になにも代...
-
【#define】 defineで定義した...
-
構造体の宣言でエラーが出ます。
-
C言語での方向キー入力判定
-
プログラムの中で別のmainを呼...
-
C言語について質問です。 子プ...
おすすめ情報