簡単な行列計算のプログラムを作ったのですが、テンプレートをしようとしたらどうしても
コンパイルできなくて困ったのでこちらに書き込みをします。
ソースは添付してあるzipにテンプレートしていないもの<nontemplate.cpp>と(こちらは問題ないです)
自分で出来るとこまでテンプレート化してあるもの<template.cpp>を入れてあります。
適当に作ったので色々とコメントがあると思いますので、そちらもお願いします。
テンプレート化できません
Re:テンプレート化できません
このあたりは最初にテンプレートをやろうとしたときに誰もが引っかかるところです。
慣れてきた今でも付け忘れてしまうことがあるくらいに。
結論からいいますとエラーとなっているところに [color=#d0d0ff" face="monospace]typename[/color]をつけると解決します。
typename は何故必要か
http://ray.sakura.ne.jp/template/typename.html
C++ Labyrinth
http://www.fides.dti.ne.jp/~oka-t/cppla ... ate-4.html
一応修正したソースもつけておきました。diffで修正箇所を確認してみて下さい。
慣れてきた今でも付け忘れてしまうことがあるくらいに。
結論からいいますとエラーとなっているところに [color=#d0d0ff" face="monospace]typename[/color]をつけると解決します。
typename は何故必要か
http://ray.sakura.ne.jp/template/typename.html
C++ Labyrinth
http://www.fides.dti.ne.jp/~oka-t/cppla ... ate-4.html
一応修正したソースもつけておきました。diffで修正箇所を確認してみて下さい。
Re:テンプレート化できません
typename の使い方ありがとうございます。
なんとなくでしかわかっていないところが分かりました。
> あ、ちなみに添付したソースでのリンクエラーの方はそのままにしてあります。
一番やって欲しいものはリンクエラーを直すことだったので、リンクエラーもお願いできませんでしょうか?
なんとなくでしかわかっていないところが分かりました。
> あ、ちなみに添付したソースでのリンクエラーの方はそのままにしてあります。
一番やって欲しいものはリンクエラーを直すことだったので、リンクエラーもお願いできませんでしょうか?
Re:テンプレート化できません
[color=#d0d0ff" face="monospace]friend std::ostream &operator<< (std::ostream &stream, Matrix<T> ob)[/color]
ご存じだと思いますが、friendをつけた上でこのように書いた場合、friendとなる対象はメンバ関数ではなく普通の関数になります。
だからこそ実装側で
[color=#d0d0ff" face="monospace]template<typename T>
std::ostream &operator<<(std::ostream &stream, Matrix<T> ob)
{
....
}[/color]
のように関数として書いたのだと思いますが、肝心の friend指定の方と定義が一致しません。なので、
[color=#d0d0ff" face="monospace]template<typename T>
class Matrix
{
....
template <typenameT>
friend std::ostream &operator<<(std::ostream &stream, Matrix<T> ob);
....
};
[/color]
とすれば一致してリンクエラーは消えるはずです。Re:テンプレート化できません
非常にややこしいところなのですが……。
クラステンプレートが,同一のテンプレート引数利用する関数テンプレートをfriendにしたい場合,
細かいことは,Justyさんがあげられていた,http://www.fides.dti.ne.jp/~oka-t/cpp-labyrinth.htmlを参照してください。
今回の場合,
# イディオムとして覚えておくのが一番かと。
個人的に考える一番の正解は,クラステンプレートのfriendはインラインで書け,ですが……。
クラステンプレートが,同一のテンプレート引数利用する関数テンプレートをfriendにしたい場合,
template <typename T> class C; template <typename T> void func (const C<T>&); template <typename T> class C { /* ... */ friend void func <T> (const c<t>&); /* ... */ };のように書きます。
細かいことは,Justyさんがあげられていた,http://www.fides.dti.ne.jp/~oka-t/cpp-labyrinth.htmlを参照してください。
今回の場合,
template <typename T> class Matrix; template <typename T> std::ostream & operator << (std::ostream & stream, Matrix<T> obj); template <typename T> class Matrix { /* ... */ friend std::ostream & operator << <T> (std::ostream & stream, Matrix<T> obj); /* ... */ };とやることになります。
# イディオムとして覚えておくのが一番かと。
個人的に考える一番の正解は,クラステンプレートのfriendはインラインで書け,ですが……。
Re:テンプレート化できません
出来ました。
コメントをくれたJustyさんYuOさんありがとうございます。
c++のテンプレート機能は私がまだなれていないだけかもしれませんが、
強力な割りに結構使いにくい感じがします。
もっと使いやすく改良をしてくれれば、c++を使う人が増えると思うのに。。
私はその強力で使いにくいことがc++を好きな理由なのですが。
コメントをくれたJustyさんYuOさんありがとうございます。
c++のテンプレート機能は私がまだなれていないだけかもしれませんが、
強力な割りに結構使いにくい感じがします。
もっと使いやすく改良をしてくれれば、c++を使う人が増えると思うのに。。
私はその強力で使いにくいことがc++を好きな理由なのですが。