C++ mapに関する質問

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
大工

C++ mapに関する質問

#1

投稿記事 by 大工 » 16年前

Map_Class では private で定義した s に map のキーを入力しそれと一致するものがあれば値を 100 に
するクラスです.問題は second 関数で実際に値を変えるのですが,関数自体を const で定義しているので
ポインタから p->second = 100; という様な操作ができません.リファレンスをみてもアドレスを渡して
該当するキーの値を変えるという関数がありませんでした.
新しく関数を作ることなく(出来ればですが・・・・^^;)該当するキーの値を変更したいのですが
可能でしょうか?
#include<iostream>
#include<string>
#include<map>

class Map_Class {

private:
	std::string s;

public:
	void second(std::map<std::string, int>&) const;
	const std::string& string_first() const {return s;}
	Map_Class(std::string ms) : s(ms) {}
};

void Map_Class::second(std::map<std::string, int>& m) const {

	std::map<std::string, int>::const_iterator it;

	if ((it=m.find(string_first()))!=m.end()) {

		 //second の値を変えたい.
	}
}

int main(void) {

	std::map<std::string, int> maps;
	std::string ss = "bb";
	Map_Class mc(ss);

	std::map<std::string, int>::iterator it = maps.begin();

	maps.insert(std::map<std::string, int>::value_type("aa", 10));
	maps.insert(std::map<std::string, int>::value_type("bb", 20));
	maps.insert(std::map<std::string, int>::value_type("cc", 30));
        //maps.insert(std::map<std::string, int>::value_type("aa", 30));
	//ここで第一引数を"aa"とすると
	//aa:10
	//bb:20
	//と表示された.

	// 変化前
	while(it != maps.end()) {

		std::cout << (*it).first << ":" << (*it).second << std::endl;
		++it;
	}

	mc.second(maps);
 
	// 変化後
	while(it != maps.end()) {

		std::cout << (*it).first << ":" << (*it).second << std::endl;
		++it;
	}

	return 0;
}
あと,付け足しなのですが insert 関数を使ってる3行目をコメントアウトしているようにしたら "aa" の値は
変わることなく2つしか表示されませんでした.これはどういう仕様なのでしょうか?

dic

Re:C++ mapに関する質問

#2

投稿記事 by dic » 16年前

std::map<std::string, int>::const_iterator it;
の行を
std::map<std::string, int>::iterator it;
に変えれば可能かと

というか C/C++ でしかも STL の話になるのですがね

大工

Re:C++ mapに関する質問

#3

投稿記事 by 大工 » 16年前

関数がconstantなのでイテレータはconstantである必要があると思います.
PCがない環境なので絶対という話ではありませんが…

たかぎ

Re:C++ mapに関する質問

#4

投稿記事 by たかぎ » 16年前

> 関数がconstantなのでイテレータはconstantである必要があると思います.

仮引数mはconst修飾されていないので、const_iteratorでなくてもかまいません。

dic

Re:C++ mapに関する質問

#5

投稿記事 by dic » 16年前

よくわかりませんが
// 変化前
it = maps.begin();
while(it != maps.end()) {

// 変化後
it = maps.begin();
while(it != maps.end()) {

のように it = maps.begin(); の入れる位置が間違っているかと
それで表示さるるとしたら
お使いのコンパイラは何でしょうか?

それとmapは重複する値の格納を許可しておりません

maps.insert(std::map<std::string, int>::value_type("aa", 10));
maps.insert(std::map<std::string, int>::value_type("aa", 20));
としても2番目はエラーが返ってきます

大工

Re:C++ mapに関する質問

#6

投稿記事 by 大工 » 16年前

たかぎさん>

なるほど・・・てっきり下のように定義したら書き換えはいかなることでも不可能だとおもってました。
void Map_Class::second(std::map<std::string, int>& m) const
関数の後に const をつけるとなにが const になるのでしょうか?

大工

Re:C++ mapに関する質問

#7

投稿記事 by 大工 » 16年前

dicさん>

it の入力値はプログラムミスです><。

開発環境はLinuxです。

なにはともあれ、mapは重複した入力は受け付けないのですね?

上書きする場合はoperator[/url]を利用するしかないのでしょうか?

たかぎ

Re:C++ mapに関する質問

#8

投稿記事 by たかぎ » 16年前

> 関数の後に const をつけるとなにが const になるのでしょうか?

そのメンバ関数を呼出す際に指定したオブジェクトがconstになります。
具体的には、
struct A
{
  void func() const;
};

A a;
a.func();
とすれば、funcメンバ関数の中では、thisの型がconst A*になります。

大工

Re:C++ mapに関する質問

#9

投稿記事 by 大工 » 16年前

なるほど

では,そのようにconstantをつけるとメンバー変数の値を参照するしか出来ないということでしょうか?さらにメンバー関数もconstantが必要?
私の質問の場合,引数の話なのでイテレータにconstantは必要ないということなのですね…?(多分…
同様にグローバルで定義してる関数はconstantは不必要…?

GPGA

Re:C++ mapに関する質問

#10

投稿記事 by GPGA » 16年前

メンバ関数にconstを付けた場合、その関数内では、mutable修飾子を付けていない全てのメンバ変数がconstになるということです。

>同様にグローバルで定義してる関数はconstantは不必要…?
const付きグローバルの関数は、宣言した時点でエラーとなります。

たかぎ

Re:C++ mapに関する質問

#11

投稿記事 by たかぎ » 16年前

> では,そのようにconstantをつけるとメンバー変数の値を参照するしか出来ないということでしょうか?

原則としてはそうです。
ただし、mutable指定子を付けた場合が例外です。
また、メンバ変数がポインタの場合、ポインタ自体はconstになりますが、その参照先まではconstにならないので要注意です。

> さらにメンバー関数もconstantが必要?

これは意味がよく分かりませんでした。

> 私の質問の場合,引数の話なのでイテレータにconstantは必要ないということなのですね…?(多分…

今回は、引数が std::map<std::string, int>& m だったからです。
const std::map<std::string, int>& m であれば、当然話が違ってきます。

> 同様にグローバルで定義してる関数はconstantは不必要…?

非メンバ関数や静的メンバ関数の場合、関数頭部の後ろにconstを付けることはできません。

dic

Re:C++ mapに関する質問

#12

投稿記事 by dic » 16年前

mapは重複したキーを認めていないので
multimapならば重複したキーを認めているのでmultimapを利用されてはいかがでしょうか?

一人で開発、保守、運用されるならば operator[/url] のオーバーロードもいいでしょうが
あまりお勧めしないです

大工

Re:C++ mapに関する質問

#13

投稿記事 by 大工 » 16年前

たかぎさん>

>さらにメンバー関数もconstantが必要?

これはconstantを付けた関数の中でまた,違うメンバー関数を呼び出すときはその関数も constant が必要?という意味です.

たかぎ

Re:C++ mapに関する質問

#14

投稿記事 by たかぎ » 16年前

> >さらにメンバー関数もconstantが必要?
> これはconstantを付けた関数の中でまた,違うメンバー関数を呼び出すときはその関数も constant が必要?という意味です.

const付きのメンバ関数からは、const付きのメンバ関数しか呼出すことができません。
thisをconst_castすることで強引にconstを外した上で、const無しのメンバ関数を呼出すことはできますが、原則としてお勧めできません。

大工

Re:C++ mapに関する質問

#15

投稿記事 by 大工 » 16年前

たかぎさん>

ふむふむ・・・なるほど

ありがとうございました.

閉鎖

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