テンプレートクラスを引数とした場合と戻り値の挙動

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

テンプレートクラスを引数とした場合と戻り値の挙動

#1

投稿記事 by chibago » 14年前

C++のgcc(g++)環境におけるテンプレートクラスの挙動に関して2点ほど
疑問に思っているところがございます。(エラーコメントも載せるべきかもしれませんが、
直接関係がないように感じますので記載は遠慮致します。)

以下は、数学のベクトル演算を行うために自作したVectorクラス(STLのものとは関係ありません)
の一つの関数でこれ自体は問題なくコンパイルできます。

template<class T>
Vector<T> Vector<T>::operator+(Vector<T> &other){
return Vector<T>(this->get_x() + other.get_x(),
this->get_y() + other.get_y(),
this->get_z() + other.get_z());
}

演算の相手となるオブジェクトであるotherは変更したくありませんので
以下のようにconstをつけたいのですが、これは通らないようです。

Vector<T> Vector<T>::operator+(const Vector<T> &other){
(これは通りません)

また、戻り値としての結果は速度が気になりますので以下のように、
参照戻しをしたいのですが、これも通りません。

Vector<T>& Vector<T>::operator+(Vector<T> &other){
(これもダメ)

この様な、現象はテンプレートクラス特有のものなのでしょうか。
基本的なことでしたら申し訳ございませんがご指導よろしくお願いします。

ちなみに、コンパイル方法としては
ソース文の最後に
template class Vector<double>;
とつけて倍精度の実装として分割コンパイルをしております.

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

Re: テンプレートクラスを引数とした場合と戻り値の挙動

#2

投稿記事 by a5ua » 14年前

コンパイルエラーのメッセージがないので、確かなことはいえませんが、
Vector<T>::get_x()(y, zも)
がconstなメンバ関数でないのが原因だと予想します。

chibago

Re: テンプレートクラスを引数とした場合と戻り値の挙動

#3

投稿記事 by chibago » 14年前

a5ua様、早速のご返事有難うございます。
ご指摘いただいた意図とあっているのか不安ですが、
template<class T>
const T Vector<T>::get_x(){
return this->x;
}
のように、戻り値にconstを付けてみました。(これ自体は通りました。)
エラーとしては以下のような物が出ております。
‘Vector<T> Vector<T>::operator+(const Vector<T>&) [with T = double]’:
Vector.cpp:116:26: instantiated from here
Vector.cpp:19:34: error: passing ‘const Vector<double>’ as ‘this’ argument of ‘const T Vector<T>::get_x() [with T = double]’ discards qualifiers
Vector.cpp:19:34: error: passing ‘const Vector<double>’ as ‘this’ argument of ‘const T Vector<T>::get_y() [with T = double]’ discards qualifiers
Vector.cpp:19:34: error: passing ‘const Vector<double>’ as ‘this’ argument of ‘const T Vector<T>::get_z() [with T = double]’ discards qualifiers

chibago

Re: テンプレートクラスを引数とした場合と戻り値の挙動

#4

投稿記事 by chibago » 14年前

すみません。
T Vector<T>::get_x() const
でしたね。constのいちが間違ってました。
御指摘のとおりに変更した結果
Vector<T>::operator+(const Vector<T>&)
の件は解決しました。
ありがとうございました。

まだ、
Vector<T>& Vector<T>::operator+(const Vector<T>&)
の参照戻しのほうはダメなようです。

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

Re: テンプレートクラスを引数とした場合と戻り値の挙動

#5

投稿記事 by a5ua » 14年前

答えになっていないかもしれませんが、
operator◇はoperator◇=を使って実装するのが一般的です。
operator+とoperator+=の実装例を示します。

コード:

template <class T>
class Vector
{
public:
	Vector &operator+=(const Vector &other)
	{
		x += other.x;
		y += other.y;
		z += other.z;
		return *this;
	}
	
	Vector operator+(const Vector &other) const
	{
		Vector result(*this);
		result += other;
		return result;
	}
private:
	T x, y, z;
};

// メンバ関数でなくても作れる
/*
Vector operator+(const Vector &lhs, const Vector &rhs)
{
	Vector result(lhs);
	result += rhs;
	return result;
}
*/

たかぎ
記事: 328
登録日時: 15年前
住所: 大阪
連絡を取る:

Re: テンプレートクラスを引数とした場合と戻り値の挙動

#6

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

chibago さんが書きました:まだ、
Vector<T>& Vector<T>::operator+(const Vector<T>&)
の参照戻しのほうはダメなようです。
これは無理です。
そもそも、返却値はどのオブジェクトの参照を返すというのでしょうか?
operator+関数内の自動オブジェクトの参照を返せないことは理解できますか?
(生存期間が終了していますので)

chibago

Re: テンプレートクラスを引数とした場合と戻り値の挙動

#7

投稿記事 by chibago » 14年前

a5ua様、
実装例有難うございます。
さっそく試してみました。
+=演算子は参照戻し(自分自身の)が可能なようですが、
+演算子はたかぎ様が御指摘のように
スコープが外れると消えてしまう自動オブジェクト
の参照を返せないということでよろしいのですね。

大変勉強になりました。
a5ua様、たかぎ様、改めて有難うございました。

chibago

Re: テンプレートクラスを引数とした場合と戻り値の挙動

#8

投稿記事 by chibago » 14年前

解決にチェックを入れるのを忘れていました。

閉鎖

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