ページ 11

C++ STL vector演算子のオーバーロードについて

Posted: 2011年8月18日(木) 15:03
by chibago
おせわになっております。
C++ STL vector演算子のオーバーロードについてですが、分からないことがございますので
教えていただければ幸です。(値渡し参照渡しの表記の仕方を完全に理解していれば問題ないのかもしれませんが)一つ目ですが、

コード:

template <typename T>
std::vector<T>& operator+=(std::vector<T> &self, const std::vector<T> &other){
  for(int i = 0; i < (int)self.size(); i++) 
    self[i] += other[i];
    return self;
}

template <typename T>
std::vector<T> operator+(const std::vector<T> &self,
                         const std::vector<T> &other){
  std::vector<T> result = self;
  result += other;
  return result;
}

このコード自体は問題なく動作しますが、+=は自分を変更するので仕方がありませんが、
+演算子の方は新しいvectorを生成するだけですので、constメソドになりそうですが、
試行錯誤してもうまくいきません。resultにselfを値渡しが出来ればいいと思いますが、
それが出来ていないだと思います。

初歩的なことだとは思いますが、まったくうまくいきません。
アドバイスをいただけると助かります。

Re: C++ STL vector演算子のオーバーロードについて

Posted: 2011年8月18日(木) 16:46
by a5ua
そのうまくいかないというコードを示してください。
あと、提示されたコードでは、other.size() < self.size()のときに範囲外アクセスになりますよ。

Re: C++ STL vector演算子のオーバーロードについて

Posted: 2011年8月18日(木) 17:33
by chibago
a5uaさん、お返事ありがとうございます。
おそらく、私の理解が不足しているだけで、晒すのも恥ずかしいものですが、
一つ目は単純にこのまま、constをつけたものです。

コード:

template <typename T>
std::vector<T> operator+(const std::vector<T> &self,
                         const std::vector<T> &other) const{
  std::vector<T> result = self;
  result += other;
  return result;
}
2つ目はコンストラクタを使って内容を渡すもので、

コード:

template <typename T>
std::vector<T> operator+(const std::vector<T> &self,
                         const std::vector<T> &other) const{
  std::vector<T> result(self);
  result += other;
  return result;
}
です。どちらも値渡しになっているので問題ないと思うのですが、
受け付けてくれません。 ただ、引数のconst std::vector<T> &self自体は
起こられませんので、selfの値渡し自体は成功しているのかもしれない
と考え混乱しております。
エラーは
エラー: non-member function ‘std::vector<T> operator+(const std::vector<T>&, const std::vector<T>&)’ cannot have cv-qualifier
でconstは付けられませんと言う程度の意味とりかいしております。

また、ご指摘いただいた範囲の違いによる例外はあまり考えておりません。
私の用途に関しては、同一長のベクトルデータの集計処理を考えております。
(Pythonの使用経験があり、Pythonでの処理を意識したものですが、
余裕があれば、例外処理の仕方を勉強して実装してみようと思います。)

Re: C++ STL vector演算子のオーバーロードについて

Posted: 2011年8月18日(木) 17:43
by chibago
すみません、分かってしまったかもしれません。
+オペレーターの演算に使用している+=がconstじゃないから
怒られているのではないかと思います。

Re: C++ STL vector演算子のオーバーロードについて

Posted: 2011年8月18日(木) 17:58
by a5ua
関数の後ろにつけるconstはメンバ関数につけるものですので、単なる関数につけることはできません。

以下のように、constメンバ関数では、thisがconstなオブジェクトへのポインタとなるので、メンバを書き換えることができなくなります。
ただの関数では、thisに相当するものがないので、そもそもconstを付ける意味がありません。

コード:

struct Hoge
{
	void hoge()
	{
		// thisの型は、"Hoge * const"
	}
	
	void hoge() const
	{
		// thisの型は、"const Hoge * const"
	}
};

Re: C++ STL vector演算子のオーバーロードについて

Posted: 2011年8月18日(木) 18:12
by chibago
a5uaさん、
ありがとうございます。
そちらが原因だったとは勉強不足でした。
てっきり、vectorクラスのメンバ関数を実装しているものと勘違いしておりました。
あくまでも、グローバル関数なんですね。