>>52
friend宣言しているfuncがメンバ関数のfuncを指していると解釈されてしまっていると思います.
スコープ解決子を使って見て下さい.

friend Matrix<X> (::func<X>)(Matrix<X> &);

ちなみに関数名の周りのカッコが無いと(Matrix<X>::func)と解釈しやがりますw.

前方宣言についてですが,
friend宣言の時点で関数テンプレートの実体化を行わせるわけですけれど,
その時点で関数テンプレートの宣言は見えていないとならないですから,
私としては前方宣言は必須だと思うのです.
gccの実装ではfriend宣言の後方にまで関数テンプレートの宣言を読みに行ってくれる
ようですが,むしろこちらの方が気が利きすぎかと思います.