テンプレートクラスの演算子オーバーロードフレンド関数をインスタンス化

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

テンプレートクラスの演算子オーバーロードフレンド関数をインスタンス化

#1

投稿記事 by いわん » 10ヶ月前

テンプレートクラスをライブラリに組み込むためにインスタンス化しようとしているのですが、
演算子オーバーロードフレンド関数のインスタンス化の方法がわかりません。
具体的には下のようなテンプレートクラスをインスタンス化します。

hoge.h

コード:

template <typename T>
class choge
{
	T m_val;
public:
	// コンストラクタ
	choge() : m_val(0) {}
	// 変換コンストラクタ
	choge(T val) : m_val(val) {}
	// +演算子オーバーロード
	choge operator+(const choge& hoge) const { return m_val + hoge.m_val; }
	// +演算子オーバーロード(フレンド関数)
	friend choge operator+(T val, const choge& hoge) { return hoge.m_val + val; }
};
インスタンス化したコードは、現状では以下のようになっています。
hoge.h

コード:

template <typename T>
class choge
{
	T m_val;
public:
	// コンストラクタ
	choge();
	// 変換コンストラクタ
	choge(T val);
	// +演算子オーバーロード
	choge operator+(const choge& hoge) const;
	// +演算子オーバーロード(フレンド関数)
	friend choge operator+(T val, const choge& hoge);
};
hoge.cpp

コード:

// コンストラクタ
template <typename T>
choge<T>::choge()
	: m_val(0)
{
}

// 変換コンストラクタ
template <typename T>
choge<T>::choge(T val)
	:m_val(val)
{
}

// +演算子オーバーロード
template <typename T>
choge<T> choge<T>::operator+(const choge<T>& hoge) const
{
	return m_val + hoge.m_val;
}

// テンプレートクラスのインスタンス化
template class choge<int>;
template class choge<double>;

// +演算子オーバーロード(フレンド関数)
choge<int> operator+(int val, const choge<int>& hoge)
{
	return hoge.m_val + val;
}
choge<double> operator+(double val, const choge<double>& hoge)
{
	return hoge.m_val + val;
}
フレンド関数はテンプレートを使わずにタイプ別に作っていてあまりかっこよくありません。
演算子オーバーロードフレンド関数をテンプレートから生成するにはどうしたらよいか教えてください。

Compiler
Visual Studio 2015
Visual C++

かずま

Re: テンプレートクラスの演算子オーバーロードフレンド関数をインスタンス化

#2

投稿記事 by かずま » 10ヶ月前

これでどうでしょうか?

hoge.h

コード:

template <typename T>
class choge
{
public:
    T m_val;
public:
    // コンストラクタ
    choge();
    // 変換コンストラクタ
    choge(T val);
    // +演算子オーバーロード
    choge operator+(const choge& hoge) const;
    // +演算子オーバーロード(フレンド関数)
    template <typename T2>
    friend choge<T2> operator+ (T2 val, const choge<T2>& hoge);
};
hoge.cpp

コード:

#include "hoge.h"

// コンストラクタ
template <typename T>
choge<T>::choge()
    : m_val(0)
{
}
 
// 変換コンストラクタ
template <typename T>
choge<T>::choge(T val)
    :m_val(val)
{
}
 
// +演算子オーバーロード
template <typename T>
choge<T> choge<T>::operator+(const choge<T>& hoge) const
{
    return m_val + hoge.m_val;
}
 
// テンプレートクラスのインスタンス化
template class choge<int>;
template class choge<double>;
 
// +演算子オーバーロード(フレンド関数)
template <typename T>
choge<T> operator+(T val, const choge<T>& hoge)
{
    return hoge.m_val + val;
}

template choge<int> operator+(int val, const choge<int>& hoge);
template choge<double> operator+(double val, const choge<double>& hoge);

かずま

Re: テンプレートクラスの演算子オーバーロードフレンド関数をインスタンス化

#3

投稿記事 by かずま » 10ヶ月前

すみません。デバッグするときに
m_val を public にしてしまいました。
public: は外してください。

また、operator+ を friend にしない方法もあります。
hoge.h

コード:

template <typename T>
class choge
{
    T m_val;
public:
    // コンストラクタ
    choge();
    // 変換コンストラクタ
    choge(T val);
    // +演算子オーバーロード
    choge operator+(const choge& hoge) const;
};

// +演算子オーバーロード
template <typename T>
choge<T> operator+ (T val, const choge<T>& hoge);
hoge.cpp

コード:

#include "hoge.h"
 
// コンストラクタ
template <typename T>
choge<T>::choge()
    : m_val(0)
{
}
 
// 変換コンストラクタ
template <typename T>
choge<T>::choge(T val)
    :m_val(val)
{
}
 
// +演算子オーバーロード
template <typename T>
choge<T> choge<T>::operator+(const choge<T>& hoge) const
{
    return m_val + hoge.m_val;
}
 
// テンプレートクラスのインスタンス化
template class choge<int>;
template class choge<double>;
 
// +演算子オーバーロード
template <typename T>
choge<T> operator+(T val, const choge<T>& hoge)
{
    return hoge + val;
}

// テンプレート関数のインスタンス化
template choge<int> operator+(int val, const choge<int>& hoge);
template choge<double> operator+(double val, const choge<double>& hoge);

アバター
いわん
記事: 24
登録日時: 2年前

Re: テンプレートクラスの演算子オーバーロードフレンド関数をインスタンス化

#4

投稿記事 by いわん » 10ヶ月前

>かずまさん
解決案ありがとうございます。
なるほど、テンプレートを入れ子にするんですね。これは使えます。
2番目の案は本ちゃんのクラスではプライベートメンバを参照するので難しいですが、参考になりました。
ありがとうございました。

アバター
いわん
記事: 24
登録日時: 2年前

Re: テンプレートクラスの演算子オーバーロードフレンド関数をインスタンス化

#5

投稿記事 by いわん » 10ヶ月前

クイック返信だと「解決!」に出来ないんですね^^;

かずま

Re: テンプレートクラスの演算子オーバーロードフレンド関数をインスタンス化

#6

投稿記事 by かずま » 10ヶ月前

いわん さんが書きました: 2番目の案は本ちゃんのクラスではプライベートメンバを参照するので難しいですが、参考になりました。
よく見てください。

 return hoge.m_val + val; ではなく
 return hoge + val; ですよ。

プライベートメンバは参照しません。

アバター
いわん
記事: 24
登録日時: 2年前

Re: テンプレートクラスの演算子オーバーロードフレンド関数をインスタンス化

#7

投稿記事 by いわん » 10ヶ月前

こちらにアップしたコードは質問用に簡素化したものでして、本チャンのクラスではプライベートメンバとして配列をもっていて全ての要素に対して演算するような処理を行っているのです(^^;。

返信

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