コンテナクラスでのエラーが出る、並びにSTLでの自作クラスの扱い方

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Iseuma14
記事: 54
登録日時: 9年前

コンテナクラスでのエラーが出る、並びにSTLでの自作クラスの扱い方

#1

投稿記事 by Iseuma14 » 8年前

お久しぶりです
2つ質問をさせていただきます


list構造を理解するために自分で簡易的なコンテナクラスListを作ってみました
以下、完成したコードです

コード:

#ifndef INCLUDE_LIST
#define INCLUDE_LIST
#include<iostream>

template<typename T>
class List
{
public:
	
	struct Node
	{
		T value;
		Node* prev;
		Node* next;
	};

private:
	Node m_eol;

public:
	List(int how = 0,int value = 0)
	{
		m_eol.prev = m_eol.next = &m_eol;
		int i;
		for(i=0;i < how;i++)
		{
			push_back(value);
		}
	}

	virtual ~List()
	{
		Clear();
	}
	
	void push_back(T value);
	void push_front(T value);
	void pop_back();
	void pop_front();
	void front_show();
	void back_show();
	void Clear();
	Node* get_first()const
	{
		return m_eol.next;
	}
	
	Node* get_eol()
	{
		return &m_eol;
	}
};

template<typename T>
void List<T>::push_back(T value)
{
	Node* next;
	next = new Node;
	Node* prev;

	prev = m_eol.prev;
	prev->next = next;
	next->next = &m_eol;
	next->prev = prev;
	m_eol.prev = next;
	next->value = value;
}

template<typename T>
void List<T>::push_front(T value)
{
	Node* prev;
	prev = new Node;
	Node* next;

	next = m_eol.next;
	next->prev = prev;
	prev->next = next;
	prev->prev = &m_eol;
	m_eol.next = prev;
	prev->value = value;
}

template<typename T>
void List<T>::pop_back()
{
	Node* node;
	node = m_eol.prev;
	Node* prev = node->prev;
	prev->next = &m_eol;
	m_eol.prev = prev;
	delete node;
}

template<typename T>
void List<T>::pop_front()
{
	Node* node;
	node = m_eol.next;
	Node* next = node->next;
	m_eol.next = next;
	next->prev = &m_eol;
	delete node;
}

template<typename T>
void List<T>::front_show()
{
	Node* node = m_eol.next;
	Node* next;
	while(node != &m_eol)
	{
		next = node->next;
		std::cout<<node->value<<std::endl;
		node = next;
	}
}

template<typename T>
void List<T>::back_show()
{
	Node* node = m_eol.prev;
	Node* prev;
	while(node != &m_eol)
	{
		prev = node->prev;
		std::cout<<node->value<<std::endl;
		node = prev;
	}
}

template<typename T>
void List<T>::Clear()
{
	Node* node;
	Node* next;
	node = m_eol.next;
	
	while(node != &m_eol)
	{
		next = node->next;
		delete node;
		node = next;
	}
}
#endif
このコードは自分の期待した通りの動作をしてくれるのですが、このテンプレートクラスのメンバ関数である、
get_first()並びにget_eol()の定義をクラスの外に出して書くと、エラーが出てしまって実行できません
以下エラーの出るコードです
問題の関数はクラスの宣言が終わった後の2つの関数です

コード:

#ifndef INCLUDE_LIST
#define INCLUDE_LIST
#include<iostream>

template<typename T>
class List
{
public:
	
	struct Node
	{
		T value;
		Node* prev;
		Node* next;
	};

private:
	Node m_eol;

public:
	List(int how = 0,int value = 0)
	{
		m_eol.prev = m_eol.next = &m_eol;
		int i;
		for(i=0;i < how;i++)
		{
			push_back(value);
		}
	}

	virtual ~List()
	{
		Clear();
	}
	
	void push_back(T value);
	void push_front(T value);
	void pop_back();
	void pop_front();
	void front_show();
	void back_show();
	void Clear();
	
};

template<typename T>
Node* List<T>::get_first()const
{
	return m_eol.next;
}

template<typename T>
Node* List<T>:: get_eol()
{
	return &m_eol;
}


template<typename T>
void List<T>::push_back(T value)
{
	Node* next;
	next = new Node;
	Node* prev;

	prev = m_eol.prev;
	prev->next = next;
	next->next = &m_eol;
	next->prev = prev;
	m_eol.prev = next;
	next->value = value;
}

template<typename T>
void List<T>::push_front(T value)
{
	Node* prev;
	prev = new Node;
	Node* next;

	next = m_eol.next;
	next->prev = prev;
	prev->next = next;
	prev->prev = &m_eol;
	m_eol.next = prev;
	prev->value = value;
}

template<typename T>
void List<T>::pop_back()
{
	Node* node;
	node = m_eol.prev;
	Node* prev = node->prev;
	prev->next = &m_eol;
	m_eol.prev = prev;
	delete node;
}

template<typename T>
void List<T>::pop_front()
{
	Node* node;
	node = m_eol.next;
	Node* next = node->next;
	m_eol.next = next;
	next->prev = &m_eol;
	delete node;
}

template<typename T>
void List<T>::front_show()
{
	Node* node = m_eol.next;
	Node* next;
	while(node != &m_eol)
	{
		next = node->next;
		std::cout<<node->value<<std::endl;
		node = next;
	}
}

template<typename T>
void List<T>::back_show()
{
	Node* node = m_eol.prev;
	Node* prev;
	while(node != &m_eol)
	{
		prev = node->prev;
		std::cout<<node->value<<std::endl;
		node = prev;
	}
}

template<typename T>
void List<T>::Clear()
{
	Node* node;
	Node* next;
	node = m_eol.next;
	
	while(node != &m_eol)
	{
		next = node->next;
		delete node;
		node = next;
	}

}
#endif
エラーメッセージは、一番上に
List.h(47): error C2143: 構文エラー : ';' が '*' の前にありません。
という部分です
しかし、確認をしてもしっかりとセミコロンもついており、原因を見つけることができません
念のためにmain関数並びにこのクラスのイテレーターの部分も載せさせていただきます(一番初めのコードで実行できているので関係している可能性は低そうです)

コード:

#include"List.h"
#include<iostream>
using namespace std;

typedef List<int>::Node Node;

class Iterator
{
protected:
	Node* m_node;

public:
	Iterator(Node* node) : m_node(node){}

	int operator *()
	{
		return m_node->value;
	}

	void operator ++()
	{
		m_node = m_node->next;
	}

	void operator ++(int)
	{
		m_node = m_node->next;
	}

	void operator --()
	{
		m_node = m_node->prev;
	}

	void operator --(int)
	{
		m_node = m_node->prev;
	}

	bool operator !=(const Iterator& other)
	{
		return m_node != other.m_node;
	}
};

void Show(Iterator first,Iterator eol)
{
	for(Iterator itr = first;itr != eol;itr++)
	{
		cout<<*itr<<endl;
	}
}

int main()
{
	List<int> list(3);
	list.front_show();
	cout<<endl;

	list.pop_back();
	list.back_show();
	cout<<endl;

	list.push_front(5);
	list.front_show();
	cout<<endl;
	
	list.push_back(10);
	Show(Iterator(list.get_first()),Iterator(list.get_eol()));
	cout<<endl;

	return 0;
}
非常に長くなってしまいました 申し訳ございません
ご回答いただけると嬉しいです
なお、コンパイラはVC++ 2010を使用しております


同時進行でSTLについても学習を進めているのですが、
例えば、座標を記録する構造体もしくはクラスがあるとします

コード:

struct position
{
        int x;
        int y;
};
これをvectorやlistといったコンテナクラスに入れて使用しようと思った時、

コード:

int main()
{
        vector<position> hoge(5);
        cout<<hoge[0].x<<endl;
}
のようにして構造体の中身を使おうとして、
.を打ち込むとvectorのメンバ関数を呼び出すことしかできずに、赤線が出て指摘されます。

自作のクラスや構造体をコンテナクラスに入れた時の自作クラスのほうのメンバの使い方を教えてください

以上です
非常に長くなってしまいました申し訳ございません

ご回答いただけると嬉しいです

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: コンテナクラスでのエラーが出る、並びにSTLでの自作クラスの扱い方

#2

投稿記事 by みけCAT » 8年前

Iseuma14 さんが書きました:このテンプレートクラスのメンバ関数である、
get_first()並びにget_eol()の定義をクラスの外に出して書くと、エラーが出てしまって実行できません
コンパイルして確かめてはいないですが、get_first()並びにget_eol()の宣言がクラス内に無いからではないでしょうか?
Iseuma14 さんが書きました:例えば、座標を記録する構造体もしくはクラスがあるとします

コード:

struct position
{
        int x;
        int y;
};
これをvectorやlistといったコンテナクラスに入れて使用しようと思った時、

コード:

int main()
{
        vector<position> hoge(5);
        cout<<hoge[0].x<<endl;
}
のようにして構造体の中身を使おうとして、
.を打ち込むとvectorのメンバ関数を呼び出すことしかできずに、赤線が出て指摘されます。

コード:

#include <iostream>
#include <vector>
using std::cout;
using std::endl;
using std::vector;

struct position
{
        int x;
        int y;
};

int main()
{
        vector<position> hoge(5);
        cout<<hoge[0].x<<endl;
}
というコードを書いたところ、
GCCclangおよびVC++で正常にコンパイルできました。
Iseuma14さんがコンパイラに渡している本物のコードを見せていただけますか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

YuO
記事: 947
登録日時: 14年前
住所: 東京都世田谷区

Re: コンテナクラスでのエラーが出る、並びにSTLでの自作クラスの扱い方

#3

投稿記事 by YuO » 8年前

Iseuma14 さんが書きました:2つ質問をさせていただきます
1トピックに対して質問は1つにした方が,回答もつきやすくなりますし,過去ログとしての価値も高くなります。
直接的に関連するならともかく,異なる内容であればトピックを分けた方が良いでしょう。
Iseuma14 さんが書きました:このコードは自分の期待した通りの動作をしてくれるのですが、このテンプレートクラスのメンバ関数である、
get_first()並びにget_eol()の定義をクラスの外に出して書くと、エラーが出てしまって実行できません
ざっと見たところ,get_firstおよびget_eol両関数がクラス内に宣言されていないようですが。
Iseuma14 さんが書きました:.を打ち込むとvectorのメンバ関数を呼び出すことしかできずに、赤線が出て指摘されます。
自作のクラスや構造体をコンテナクラスに入れた時の自作クラスのほうのメンバの使い方を教えてください
std::vector<T>::operator[]はT&を返しますから,普通にオブジェクトのメンバを.に続けて書くことができます。

問題となっているのは,
  • コンパイルするとコンパイラがエラーを発生させる
  • コンパイル時にコンパイラはエラーを発生させない
のどちらでしょうか。
  • 前者であれば,コンパイル時のエラーメッセージは何でしょうか。
  • 後者であるならば,VS2010のC++対応における不具合の可能性がありますから,MSDN フォーラムにでも投げてみると何か反応があるかもしれません。
    ただし、VS 2010ではまともなbug fix対応はされない可能性が高いでしょう。
    Visual Studio 2010 Service Pack 1はすでに延長サポートフェーズに入っていますので。
    ref) マイクロソフト サポート ライフサイクル
    そして、この問題はセキュリティ問題とは考えにくいため、延長サポートフェーズにおいて期待できる内容ではありません。

Iseuma14
記事: 54
登録日時: 9年前

Re: コンテナクラスでのエラーが出る、並びにSTLでの自作クラスの扱い方

#4

投稿記事 by Iseuma14 » 8年前

みけCAT様いつもご回答ありがとうございます
①につきましては、完成したin-lineにしてあるコードを切り取り、ペーストしたため
メンバの宣言部分が消えていたようです お手数おかけしました
正しいコードは以下になります 以下でも同様のエラーが発生しました

コード:

#ifndef INCLUDE_LIST
#define INCLUDE_LIST
#include<iostream>

template<typename T>
class List
{
public:
	
	struct Node
	{
		T value;
		Node* prev;
		Node* next;
	};

private:
	Node m_eol;

public:
	List(int how = 0,int value = 0)
	{
		m_eol.prev = m_eol.next = &m_eol;
		int i;
		for(i=0;i < how;i++)
		{
			push_back(value);
		}
	}

	virtual ~List()
	{
		Clear();
	}
	
	void push_back(T value);
	void push_front(T value);
	void pop_back();
	void pop_front();
	void front_show();
	void back_show();
	void Clear();
	Node* get_first()const;
	Node* get_eol();
	
};

template<typename T>
Node* List<T>::get_first()const
{
	return m_eol.next;
}

template<typename T>
Node* List<T>::get_eol()
{
	return &m_eol;
}

template<typename T>
void List<T>::push_back(T value)
{
	Node* next;
	next = new Node;
	Node* prev;

	prev = m_eol.prev;
	prev->next = next;
	next->next = &m_eol;
	next->prev = prev;
	m_eol.prev = next;
	next->value = value;
}

template<typename T>
void List<T>::push_front(T value)
{
	Node* prev;
	prev = new Node;
	Node* next;

	next = m_eol.next;
	next->prev = prev;
	prev->next = next;
	prev->prev = &m_eol;
	m_eol.next = prev;
	prev->value = value;
}

template<typename T>
void List<T>::pop_back()
{
	Node* node;
	node = m_eol.prev;
	Node* prev = node->prev;
	prev->next = &m_eol;
	m_eol.prev = prev;
	delete node;
}

template<typename T>
void List<T>::pop_front()
{
	Node* node;
	node = m_eol.next;
	Node* next = node->next;
	m_eol.next = next;
	next->prev = &m_eol;
	delete node;
}

template<typename T>
void List<T>::front_show()
{
	Node* node = m_eol.next;
	Node* next;
	while(node != &m_eol)
	{
		next = node->next;
		std::cout<<node->value<<std::endl;
		node = next;
	}
}

template<typename T>
void List<T>::back_show()
{
	Node* node = m_eol.prev;
	Node* prev;
	while(node != &m_eol)
	{
		prev = node->prev;
		std::cout<<node->value<<std::endl;
		node = prev;
	}
}

template<typename T>
void List<T>::Clear()
{
	Node* node;
	Node* next;
	node = m_eol.next;
	
	while(node != &m_eol)
	{
		next = node->next;
		delete node;
		node = next;
	}

}
#endif
②に関しては、自分が作っていたプログラムでは要素番号を指定し忘れていたため、vectorのメンバ関数が呼ばれたしまっていたようです
勘違いでした失礼いたしました

①に関してはまた余裕があればご回答いただけると嬉しいです

Iseuma14
記事: 54
登録日時: 9年前

Re: コンテナクラスでのエラーが出る、並びにSTLでの自作クラスの扱い方

#5

投稿記事 by Iseuma14 » 8年前

YuO様ご回答ありがとうございます

みけCAT様へのご返信で書いたこととほとんど重複ですが、
①につきましては、完成したinlineにしてあるコードを切り取り、ペーストして貼り付けたため
メンバの宣言部分が消えていたようです お手数おかけしました
正しいコードは以下になります 以下でも同様のエラーが発生しました お暇あればまたご回答よろしくお願いします

コード:

#ifndef INCLUDE_LIST
#define INCLUDE_LIST
#include<iostream>

template<typename T>
class List
{
public:
	
	struct Node
	{
		T value;
		Node* prev;
		Node* next;
	};

private:
	Node m_eol;

public:
	List(int how = 0,int value = 0)
	{
		m_eol.prev = m_eol.next = &m_eol;
		int i;
		for(i=0;i < how;i++)
		{
			push_back(value);
		}
	}

	virtual ~List()
	{
		Clear();
	}
	
	void push_back(T value);
	void push_front(T value);
	void pop_back();
	void pop_front();
	void front_show();
	void back_show();
	void Clear();
	Node* get_first()const;
	Node* get_eol();
	
};

template<typename T>
Node* List<T>::get_first()const
{
	return m_eol.next;
}

template<typename T>
Node* List<T>::get_eol()
{
	return &m_eol;
}

template<typename T>
void List<T>::push_back(T value)
{
	Node* next;
	next = new Node;
	Node* prev;

	prev = m_eol.prev;
	prev->next = next;
	next->next = &m_eol;
	next->prev = prev;
	m_eol.prev = next;
	next->value = value;
}

template<typename T>
void List<T>::push_front(T value)
{
	Node* prev;
	prev = new Node;
	Node* next;

	next = m_eol.next;
	next->prev = prev;
	prev->next = next;
	prev->prev = &m_eol;
	m_eol.next = prev;
	prev->value = value;
}

template<typename T>
void List<T>::pop_back()
{
	Node* node;
	node = m_eol.prev;
	Node* prev = node->prev;
	prev->next = &m_eol;
	m_eol.prev = prev;
	delete node;
}

template<typename T>
void List<T>::pop_front()
{
	Node* node;
	node = m_eol.next;
	Node* next = node->next;
	m_eol.next = next;
	next->prev = &m_eol;
	delete node;
}

template<typename T>
void List<T>::front_show()
{
	Node* node = m_eol.next;
	Node* next;
	while(node != &m_eol)
	{
		next = node->next;
		std::cout<<node->value<<std::endl;
		node = next;
	}
}

template<typename T>
void List<T>::back_show()
{
	Node* node = m_eol.prev;
	Node* prev;
	while(node != &m_eol)
	{
		prev = node->prev;
		std::cout<<node->value<<std::endl;
		node = prev;
	}
}

template<typename T>
void List<T>::Clear()
{
	Node* node;
	Node* next;
	node = m_eol.next;
	
	while(node != &m_eol)
	{
		next = node->next;
		delete node;
		node = next;
	}

}
#endif

②に関しましては
自分の作ったプログラムのほうにてvectorで作った配列の要素番号を入力せず
.を使っていたため、vectorのメンバしか呼べなかったようです 勘違いでした 申し訳ございません

①につきましてはお暇あればまたご回答いただけると嬉しいです

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: コンテナクラスでのエラーが出る、並びにSTLでの自作クラスの扱い方

#6

投稿記事 by みけCAT » 8年前

Nodeはクラスの中でしか定義されていないのでList<T>::Nodeとして、
さらに自分はよくわかっていないですがこれはdependent nameなので前にtypenameをつけないといけないらしいです。
c++ - Compiling error on template method, return is instance from inner class - Stack Overflow

コード:

template<typename T>
typename List<T>::Node* List<T>::get_first()const
{
	return m_eol.next;
}

template<typename T>
typename List<T>::Node* List<T>::get_eol()
{
	return &m_eol;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Iseuma14
記事: 54
登録日時: 9年前

Re: コンテナクラスでのエラーが出る、並びにSTLでの自作クラスの扱い方

#7

投稿記事 by Iseuma14 » 8年前

みけCAT様
ご回答ありがとうございます

dependent nameですか
初めて知ることでしたので非常に参考になりました

無事ビルド、実行できました
本当にありがとうございました

閉鎖

“C言語何でも質問掲示板” へ戻る