listクラスでもoperator[]が使えれば便利だと思うんだ。

アバター
MoNoQLoREATOR
記事: 284
登録日時: 14年前
住所: 東京

listクラスでもoperator[]が使えれば便利だと思うんだ。

投稿記事 by MoNoQLoREATOR » 14年前

というわけで、9割方 書き終わりました。

以下ソースコード

CODE:

#include 

template 

class slist{
	std::list myList;

	public:

	SLIST& operator[] (const int &num){
		std::list::iterator it = myList.begin();
		for(int i=0;i &list){		myList.merge(list);	}
	void pop_back(){		myList.pop_back();	}
	void push_back(SLIST &ele){		myList.push_back(ele);	}
	void remove(SLIST &ele){		myList.remove(ele);	}
	void resize(const int num){		myList.resize(num);	}
	unsigned int size(){		return myList.size();	}
	void sort(){		myList.sort();	}

	std::list& operator= (std::list &list){
		myList = list;
		return *myList;
	}

	std::list& operator+ (std::list &list){
		return myList + list;
	}

	std::list& operator+ (SLIST &ele){
		return myList + ele;
	}

	void operator+= (std::list &list){
		myList.merge(list);
	}

	void operator+= (SLIST &ele){
		myList.push_back(ele);
	}

	void operator-- (void){
		myList.pop_back();
	}

	void operator! (void){
		myList.clear();
	}
};

int main(){}
あとはちゃんと動作するかテストするぐらいですね。(operator+のところが怪しい)
しかし、1つだけ実装していない機能があります。
sort()
です。本家listクラスでは、オプションとしてソート方法を設定できるらしいですが、私には理解できませんでした。ためしに

CODE:

void sort(){		myList.sort();	}
	void sort(Comparison comp){
		myList.sort(comp);
	}
としてみたのですが、「構文エラー : 識別子 'Comparison'」と言われてしまいました。何かをインクルードしなくてはいけないのですかね?(でもVisualC++であれば必要ないはずですが)
しかもlistクラスにはあと2種類あるんですよね。型がわからないことにはどうしようもないぜ・・・。
わかる方おねがいします。

アバター
bitter_fox
記事: 607
登録日時: 14年前

Re: listクラスでもoperator[]が使えれば便利だと思うんだ。

投稿記事 by bitter_fox » 14年前

委譲を用いたアダプタパターンじゃなくって継承を用いた実装をしてはどうですか?
最後に編集したユーザー bitter_fox on 2011年8月05日(金) 16:17 [ 編集 1 回目 ]

アバター
GRAM
記事: 164
登録日時: 14年前

Re: listクラスでもoperator[]が使えれば便利だと思うんだ。

投稿記事 by GRAM » 14年前

こういってはなんなのですが
slistというのはSGI版STLに採用されている非標準の単方向リストの名前とかぶってます
まぁ自分で使う分にはあんま関係ないでしょうけど・・・

アバター
MoNoQLoREATOR
記事: 284
登録日時: 14年前
住所: 東京

Re: listクラスでもoperator[]が使えれば便利だと思うんだ。

投稿記事 by MoNoQLoREATOR » 14年前

なるほど!その手がありましたね!!
・・・と思ったのですが、

CODE:

	SLIST& operator[] (const int &num){
		std::list::iterator it = myList.begin();
		for(int i=0;i<num;i++) it++;
		return *it;
	}
の myList.begin() の部分はどうすればよいのでしょうか?

アバター
bitter_fox
記事: 607
登録日時: 14年前

Re: listクラスでもoperator[]が使えれば便利だと思うんだ。

投稿記事 by bitter_fox » 14年前

MoNoQLoREATOR さんが書きました:なるほど!その手がありましたね!!
・・・と思ったのですが、

CODE:

	SLIST& operator[] (const int &num){
		std::list::iterator it = myList.begin();
		for(int i=0;i::iterator it = std::list::begin();
		std::list::iterator it = this->begin();

アバター
MoNoQLoREATOR
記事: 284
登録日時: 14年前
住所: 東京

Re: listクラスでもoperator[]が使えれば便利だと思うんだ。

投稿記事 by MoNoQLoREATOR » 14年前

ありがとうございます。
ところで、

CODE:

class slist :public list{
	std::list::iterator itBeg;
	std::list::iterator itEnd;
};
とするとエラーが出るのですが何故でしょう?

アバター
bitter_fox
記事: 607
登録日時: 14年前

Re: listクラスでもoperator[]が使えれば便利だと思うんだ。

投稿記事 by bitter_fox » 14年前

MoNoQLoREATOR さんが書きました:

CODE:

class slist :public list{
	std::list::iterator itBeg;
	std::list::iterator itEnd;
};
とするとエラーが出るのですが何故でしょう?
親のlistにも型引数を与える必要があるのではないですか?

アバター
MoNoQLoREATOR
記事: 284
登録日時: 14年前
住所: 東京

Re: listクラスでもoperator[]が使えれば便利だと思うんだ。

投稿記事 by MoNoQLoREATOR » 14年前

CODE:

class slist :public list{
    std::list::iterator itBeg;
    std::list::iterator itEnd;
};
のときは「'std::list::iterator' : 依存名は型ではありません」と言われ、

CODE:

class slist :public list{
    std::list::iterator itBeg;
    std::list::iterator itEnd;
};
とすると構文エラーだと言われました。

それとも、親のlistに型引数を与えるということはもっと違うことなのですか?

アバター
bitter_fox
記事: 607
登録日時: 14年前

Re: listクラスでもoperator[]が使えれば便利だと思うんだ。

投稿記事 by bitter_fox » 14年前

MoNoQLoREATOR さんが書きました:

CODE:

class slist :public list{
    std::list::iterator itBeg;
    std::list::iterator itEnd;
};
std::が省略されてますが、名前空間stdを使用するように宣言してますよね?

[hr][追記]
名前空間を補えばコンパイルできることをbcc(5.5.1)で確認したのですが比較的新しい環境(gcc(4.3.4))ではうまくコンパイルできませんでした・・・

どうやらtypedef typename std::list::iterator iterator;としてiteratorを定義すればコンパイルが通るようです。
http://ideone.com/R1lYv
a5ua さんが書きました: std::list::iteratorと書いたとき、iteratorが型名であるかどうかはSLISTに依存しているため、
std::list::iteratorが型名であることをコンパイラに対して明示するために、typenameキーワードを付ける必要があります。
ほぉ、そんな理由があったんですか。
最後に編集したユーザー bitter_fox on 2011年8月06日(土) 04:34 [ 編集 2 回目 ]

アバター
a5ua
記事: 199
登録日時: 14年前

RE: listクラスでもoperator[]が使えれば便利だと思うんだ。

投稿記事 by a5ua » 14年前

std::list::iteratorと書いたとき、iteratorが型名であるかどうかはSLISTに依存しているため、
std::list::iteratorが型名であることをコンパイラに対して明示するために、typenameキーワードを付ける必要があります。

CODE:

#include 
#include 	// for std::advance

template 
class slist : public std::list
{
public:
	SLIST &operator[](int index)
	{
		typename std::list::iterator it = begin();
		std::advance(it, index);
		return *it;
	}
};
std::advanceはイテレータを指定した数だけすすめる関数です。


余談ですが、C++の次期規格では、イテレータを指定した数だけ進めて、そのイテレータを戻り値として返すstd::nextという関数が用意されています。
(コンパイラによっては、すでに実装されています。)これを使うと、もっとシンプルに以下のように書けます。

CODE:

#include 
#include 	// for std::next

template 
class slist : public std::list
{
public:
	SLIST &operator[](int index)
	{
		return *std::next(begin(), index);
	}
};
(追記)
イテレータの型は、std::listの方で定義されているので、単純にiteratorと書けばよかったですね。
ついでに戻り値の参照型も、定義されているもの(reference)を使っておきましょう。

CODE:

#include 
#include 
 
template 
class slist : public std::list
{
public:
    reference operator[](int index)
    {
        iterator it = begin();
        std::advance(it, index);
        return *it;
        //return *std::next(begin(), index);
    }
};
最後に編集したユーザー a5ua on 2011年8月06日(土) 05:34 [ 編集 2 回目 ]

アバター
MoNoQLoREATOR
記事: 284
登録日時: 14年前
住所: 東京

Re: listクラスでもoperator[]が使えれば便利だと思うんだ。

投稿記事 by MoNoQLoREATOR » 14年前

>>bitter_foxさん
>>a5uaさん
ありがとうございます。コンパイル通りました。
今テストをしているのですが、operator+=を使うと、コマンドプロンプトが一瞬で消滅しますorz
先は長いぜ・・・。