テンプレート化できません

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

テンプレート化できません

#1

投稿記事 by 組木紙織 » 18年前

簡単な行列計算のプログラムを作ったのですが、テンプレートをしようとしたらどうしても
コンパイルできなくて困ったのでこちらに書き込みをします。

ソースは添付してあるzipにテンプレートしていないもの<nontemplate.cpp>と(こちらは問題ないです)
自分で出来るとこまでテンプレート化してあるもの<template.cpp>を入れてあります。

適当に作ったので色々とコメントがあると思いますので、そちらもお願いします。

Justy

Re:テンプレート化できません

#2

投稿記事 by Justy » 18年前

 このあたりは最初にテンプレートをやろうとしたときに誰もが引っかかるところです。
 慣れてきた今でも付け忘れてしまうことがあるくらいに。


 結論からいいますとエラーとなっているところに [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で修正箇所を確認してみて下さい。

Justy

Re:テンプレート化できません

#3

投稿記事 by Justy » 18年前

 あ、ちなみに添付したソースでのリンクエラーの方はそのままにしてあります。

組木紙織

Re:テンプレート化できません

#4

投稿記事 by 組木紙織 » 18年前

typename の使い方ありがとうございます。
なんとなくでしかわかっていないところが分かりました。

> あ、ちなみに添付したソースでのリンクエラーの方はそのままにしてあります。

一番やって欲しいものはリンクエラーを直すことだったので、リンクエラーもお願いできませんでしょうか?

Justy

Re:テンプレート化できません

#5

投稿記事 by Justy » 18年前

[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]
 とすれば一致してリンクエラーは消えるはずです。

YuO

Re:テンプレート化できません

#6

投稿記事 by YuO » 18年前

非常にややこしいところなのですが……。

クラステンプレートが,同一のテンプレート引数利用する関数テンプレートを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:テンプレート化できません

#7

投稿記事 by 組木紙織 » 18年前

出来ました。

コメントをくれたJustyさんYuOさんありがとうございます。

c++のテンプレート機能は私がまだなれていないだけかもしれませんが、
強力な割りに結構使いにくい感じがします。
もっと使いやすく改良をしてくれれば、c++を使う人が増えると思うのに。。

私はその強力で使いにくいことがc++を好きな理由なのですが。

閉鎖

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