合計 昨日 今日

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

[このトピックは解決済みです]

フォーラムルール
フォーラムルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Name: いわん
[URL]
入門者(3,474 ポイント)
Date: 2017年8月11日(金) 12:04
No: 1
(OFFLINE)

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

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

hoge.h
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// コンストラクタ
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++

Name: かずま
[URL]
Date: 2017年8月11日(金) 16:19
No: 2
(OFFLINE)

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

これでどうでしょうか?

hoge.h
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#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);

Name: かずま
[URL]
Date: 2017年8月11日(金) 19:51
No: 3
(OFFLINE)

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

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

また、operator+ を friend にしない方法もあります。
hoge.h
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#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);

Name: いわん
[URL]
入門者(3,474 ポイント)
Date: 2017年8月11日(金) 22:09
No: 4
(OFFLINE)

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

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

Name: いわん
[URL]
入門者(3,474 ポイント)
Date: 2017年8月11日(金) 22:24
No: 5
(OFFLINE)

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

[解決!]

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

Name: かずま
[URL]
Date: 2017年8月11日(金) 22:31
No: 6
(OFFLINE)

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

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

よく見てください。

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

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

Name: いわん
[URL]
入門者(3,474 ポイント)
Date: 2017年8月12日(土) 12:47
No: 7
(OFFLINE)

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

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


Return to C言語何でも質問掲示板

オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[25人]