ページ 11

テンプレートクラスの継承

Posted: 2010年9月22日(水) 09:24
by ぬっち
いつもお世話になっております。

今回は、C++で(初歩的な?)質問をさせていただきたいと思います。
質問の内容は、タイトルのとおりで、テンプレートクラスの継承についてです。
例えば、基底のテンプレートクラスBaseがあったとして、この基底クラスをpublic継承して、非テンプレートクラスDerivedを作ることを考えます。
大体のコードは以下のようになっています。
template < typename Type1, typename Type2 >
class Base
{
protected:
    Type1 m_A;
    Type2 m_B;
public:
//コンストラクタなどは省略。デストラクタは継承も考えて、仮想関数としてある。
};

class Derived : public Base < std::basic_string < char >, int >
{
public:
//コンストラクタなどは省略。
    bool Compare( std::basic_string < char > a ); //std::basic_string < char >との比較を行う。
};

bool Derived::Compare( std::basic_string < char > a )
{
    return m_A == a;
}
これで、コンパイルを実行すると、Derived::Compare内で「==型の左オペランドを扱う演算子が見つかりません」というエラーが現れてしまいます。
これにはどこが問題があるのでしょうか?
テンプレートの型を決めたものを継承すること自体が問題なのでしょうか?

ソースコードも要点のみしか書いていなく、わかりづらいかもしれませんがよろしくお願いします。

Re:テンプレートクラスの継承

Posted: 2010年9月22日(水) 12:00
by jay
bool Derived::Compare( std::basic_string < char > a )
{
return m_A == a;
}

の部分に問題があるように思われます

"return"はその文の制御を終了して、必要に応じて戻り値を返すものです。
また"=="はその左の式と右の式が正しいかどうかを判断する時に使います。
つまり"=="はif文等の条件式に使われます。
右の値を左に代入するときは"="を使います。



bool Derived::Compare( std::basic_string < char > a )
{
m_A = a;
return m_A;
}


こうすれば動くと思いますが、パッと見ただけなので他にも可笑しい所があるかもしれませんね・・・。



画像

Re:テンプレートクラスの継承

Posted: 2010年9月22日(水) 12:34
by ぬっち
jayさん返信ありがとうございます。

私が行いたいのは、Compareメソッドで比較を行いたいわけです。
ですから代入するのではなくて、Compareメソッドの引数でとったものと、メンバ変数との比較をして、その結果を返したいのです。
そのため、
return m_A == a;
としても問題ないと思うのですが・・・。
実際に、他のクラスのメソッドでも同様のことを行っていますが、今のところ問題ありません。
私の理解違いかもしれませんが・・・。

Re:テンプレートクラスの継承

Posted: 2010年9月22日(水) 13:03
by Blue
開発環境は何ですか?
一応コピペしてコンパイルしましたがVS2005だと普通に動きました。

Re:テンプレートクラスの継承

Posted: 2010年9月22日(水) 13:03
by ookami
あら、こちらの環境ではエラーが出ません。
コンパイルもリンクも通りました。恐らく意図通りに動いていると思われます。

Visual C++ 2005 express edition
Windows XP pro

です。
そちらの環境はどんな感じですか?

--
クラスの中身は変更していません。

#include <stdio.h>
#include <string>

template < typename Type1, typename Type2 >
class Base
{
protected:
Type1 m_A;
Type2 m_B;
public:
//コンストラクタなどは省略。デストラクタは継承も考えて、仮想関数としてある。
};

class Derived : public Base < std::basic_string < char >, int >
{
public:
//コンストラクタなどは省略。
bool Compare( std::basic_string < char > a ); //std::basic_string < char >との比較を行う。
};

bool Derived::Compare( std::basic_string < char > a )
{
return m_A == a;
}

void main(void)
{
Derived d;
std::basic_string < char > a;
printf("%d\n",d.Compare(a));
}

Re:テンプレートクラスの継承

Posted: 2010年9月22日(水) 13:08
by jay
成る程、真か偽かを返す訳ですね(汗)

と、どうやら僕は場違いのようなのでどこかに行きますね~
結局お役に立てず申し訳ないです・・・。

Re:テンプレートクラスの継承

Posted: 2010年9月22日(水) 13:09
by めるぽん
#include <string>

// ここに上記のコードを貼り付ける
 
int main()
{
    Derived d;
    d.Compare("abcd");
}
下記のコードを GCC4.3.4 と VC9 でコンパイルしましたが、コンパイルエラーは起きませんでした。

Re:テンプレートクラスの継承

Posted: 2010年9月22日(水) 13:53
by ぬっち
皆様返信ありがとうございます。

環境を書いていませんでしたね、すいません;;

<コンパイル環境>
・コンパイラ : Visual C++ 2010 Express
・OS : Windows7 Home Premium 64bit

です。他に書いたほうがいいことがあれば、教えてください。

実際は、こんな簡単なクラスの構造をしているわけではないのですが、わかりやすさのためエラー部分を見て必要と思われるところをピックアップして掲載しました。
この条件判定は、for文で使用する予定でしたが、returnに書いても同じエラーが生じたため、returnのほうを採用しました。
必要があれば、全ソースコードを掲載しようと考えています。

よろしくお願いします。

Re:テンプレートクラスの継承

Posted: 2010年9月22日(水) 14:13
by うしお
これはテンプレート継承が原因ではないと思います

#include <string>
はきちんとされていますか?

これがない場合、
basic_string < char > a;
の宣言は可能ですが、
比較ができないようです

#include <string>がない場合、

basic_string < char > tes0,tes1;
if(tes0 == tes1){

}
たったこれだけで同じエラーです
確認してみてください

Re:テンプレートクラスの継承

Posted: 2010年9月22日(水) 14:13
by Blue
ちなみにookamiさんの載せていただいたコードをまっさらなプロジェクトに
入れてコンパイルしてもエラーになりますか?

ならないのであれば、別のところが怪しいかも。

Re:テンプレートクラスの継承

Posted: 2010年9月22日(水) 14:25
by ぬっち
うしおさん、Blueさん返信ありがとうございます。

お恥ずかしいですがうしおさんの仰るように、なぜか必要のない
#include <iostream>
があって、
#include <string>
をするのを忘れていました;;

宣言だけ出来るというのは盲点でした^^;
本当に初歩的な問題でお騒がせしてしまい申し訳ありませんでした。

ありがとうございました。 画像