ページ 1 / 1
テンプレート化できません
Posted: 2007年5月13日(日) 18:54
by 組木紙織
簡単な行列計算のプログラムを作ったのですが、テンプレートをしようとしたらどうしても
コンパイルできなくて困ったのでこちらに書き込みをします。
ソースは添付してあるzipにテンプレートしていないもの<nontemplate.cpp>と(こちらは問題ないです)
自分で出来るとこまでテンプレート化してあるもの<template.cpp>を入れてあります。
適当に作ったので色々とコメントがあると思いますので、そちらもお願いします。
Re:テンプレート化できません
Posted: 2007年5月13日(日) 20:08
by Justy
このあたりは最初にテンプレートをやろうとしたときに誰もが引っかかるところです。
慣れてきた今でも付け忘れてしまうことがあるくらいに。
結論からいいますとエラーとなっているところに [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:テンプレート化できません
Posted: 2007年5月13日(日) 20:28
by Justy
あ、ちなみに添付したソースでのリンクエラーの方はそのままにしてあります。
Re:テンプレート化できません
Posted: 2007年5月13日(日) 21:53
by 組木紙織
typename の使い方ありがとうございます。
なんとなくでしかわかっていないところが分かりました。
> あ、ちなみに添付したソースでのリンクエラーの方はそのままにしてあります。
一番やって欲しいものはリンクエラーを直すことだったので、リンクエラーもお願いできませんでしょうか?
Re:テンプレート化できません
Posted: 2007年5月13日(日) 22:30
by Justy
[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:テンプレート化できません
Posted: 2007年5月13日(日) 23:44
by YuO
非常にややこしいところなのですが……。
クラステンプレートが,同一のテンプレート引数利用する関数テンプレートを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:テンプレート化できません
Posted: 2007年5月14日(月) 21:32
by 組木紙織
出来ました。
コメントをくれたJustyさんYuOさんありがとうございます。
c++のテンプレート機能は私がまだなれていないだけかもしれませんが、
強力な割りに結構使いにくい感じがします。
もっと使いやすく改良をしてくれれば、c++を使う人が増えると思うのに。。
私はその強力で使いにくいことがc++を好きな理由なのですが。