0

私は、OpenGLを学ぶことの一環としてベクトルと行列を実装する単純なクラスを書いています。私はこのように見える行列とベクトルのクラスがあります。私はそれが内部m_dataメンバーにアクセスできるようにしたいのでテンプレート友人機能のこの部分的な特殊化はなぜ機能しますか?

// Forward declarations 
template <typename T, size_t N/*len*/> struct vec; 
template<typename T, size_t N /*rows*/, size_t M /*cols*/> struct mat; 

// Forward declare *operator for matrix 
// (NxM) matrix multiplied by (MxP) matrix yields (NxP) matrix 
mat<T, N, P> operator* (const mat<T, N, M>& A, const mat<T, M, P>& B); 

template <typename T, size_t N> 
struct vec { 
    public: 
     vec() {} 
     virtual ~vec() {} 
    private: 
     T[N] m_data; 
}; 

template <typename T, size_t N, size_t M> 
struct mat { 
    public: 
     mat() {} 
     virtual ~mat() {} 
     // This is where it gets interesting. By my reading of the rules 
     // of C++11, this counts as a partial specialization of the 
     // operator template, and should not work. 
     // However, it compiles just fine! 
     template <size_t n, size_t m, size_t p> 
     friend mat<T, n, p> operator* (const mat<T, n, m>& A, 
             const mat<T, m, p> &B); 
     // Implementation appears later in the same header file. 
    private: 
     T[N*M] m_data; 
}; 

を私は友人と*演算子を宣言したが、私はマット」のユーザーを望んでいません'と' vec 'を使って内部を知ることができます。

これはうまくコンパイルされて実行されます。私はその行列の乗算のための単体テストを持っており、うまく動作します。しかし、私はそれがなぜコンパイルされているのか分かりません。 C++テンプレートのルールを読んだことで、*演算子の宣言は、関数テンプレートの部分的な特殊化としてカウントされ、違法です。

私はここで何が欠けていますか?

+1

プログラムを正常にビルドするために使用した残りのコードを追加してください。 –

答えて

0

このようになります* NOT *コンパイル。私が思っていたときに単体テストでテンプレートストリーム演算子を呼び出さなかったので、コンパイルしていると思いました。

申し訳ありません愚かな質問です!

関連する問題