2012-02-23 10 views
0

これで、テンプレートクラスに< <演算子がオーバーロードされてしまいました。条件は、< <演算子がこのクラスに対して定義されたvoid print関数を呼び出さなければならないという要件です。ここで演算子<<プリント機能を呼び出すためにオーバーロードすると問題が発生する

は、テンプレートのヘッダから重要なものである:

template <class T> 
class MyTemp { 
public: 
    MyTemp();   //constructor 

    friend std::ostream& operator<< (std::ostream& os, const MyTemp<T>& a); 

    void print(std::ostream& os, char ofc = ' ') const; 

、ここでは私の印刷機能がある基本的には、最初に、ベクター及び印刷物最後の要素です:どのように私

template <class T> 
void Stack<T>::print(std::ostream& os, char ofc = ' ') const 
{ 
    for (int i = (fixstack.size()-1); i >= 0 ; --i) 
    { 
     os << fixstack[i] << ofc; 
    } 
} 

、ここでは、オペレーターを持っている< <は、オーバーロードされました:

template <class T> 
std::ostream& operator<< (std::ostream& os, const Stack<T>& a) 
{ 
    // So here I need to call the a.print() function 
} 

しかし、 "未解決の外部シンボル"エラーが表示されます。だから本当に私は2つの問題があると思う。最初は、上記のエラーを修正する方法です。第二に、一度それが固定されたら私はちょうどa.print(os)inside < <を過負荷と呼ぶでしょうか?私はそれがostreamを返す必要があることを知っている。どんな助けでも大歓迎です!

+1

このfaqを読んでください:http://www.parashift.com/c++-faq/templates.html#faq-35.16 –

+0

最初のスニペットでクラステンプレート「MyTemp」を呼び出し、他のスニペットでは「Stack」を呼び出します。あなたは実際のコードでそれをしますか? –

答えて

2

最も簡単なことは、printを公開しておくことです(例のように)ので、オペレータは友人である必要はありません。あなたはそれがプライベートである必要がない場合は

template <class T> 
class MyTemp { 
public: 
    void print(std::ostream& os, char ofc = ' ') const; 
}; 

template <class T> 
std::ostream& operator<< (std::ostream& os, const MyTemp<T>& a) { 
    a.print(os); 
    return os; 
} 

は、その後、あなたは友人になる正しいテンプレートの特殊化を宣言する必要があります - あなたのfriend宣言は、周囲の名前空間における非鋳型オペレータではなく、テンプレートを宣言します。残念ながら、テンプレートあなたは事前にそれを宣言する必要があります友人作るために:

// Declare the templates first 
template <class T> class MyTemp; 
template <class T> std::ostream& operator<< (std::ostream&, const MyTemp<T>&); 

template <class T> 
class MyTemp { 
public: 
    friend std::ostream& operator<< <>(std::ostream& os, const MyTemp<T>& a); 
    // With a template thingy here ^^ 

private: 
    void print(std::ostream& os, char ofc = ' ') const; 
}; 

template <class T> 
std::ostream& operator<< (std::ostream& os, const MyTemp<T>& a) { 
    a.print(os); 
    return os; 
} 

それとも、オペレータインライン定義することができます:あなたの最後の質問について

template <class T> 
class MyTemp { 
public: 
    friend std::ostream& operator<<(std::ostream& os, const MyTemp<T>& a) { 
     a.print(os); 
     return os; 
    } 

private: 
    void print(std::ostream& os, char ofc = ' ') const; 
}; 

を:

第二に、一度それが固定されている私はちょうどa.print(os)<<の負荷を呼び出すだろうか?私はそれがostreamを返す必要があることを知っている。

実際にはostreamを返す必要があります。私のサンプルコードのように、渡されたものを返すだけです。

+0

ああ、完璧にありがとう!私のテンプレートスキルに取り組む必要があります。私は将来この情報を念頭に置いていきます。 – Doug

0

printメンバーの機能は公開されているため、operator<<friendと宣言する必要はありません。

このエラーは、uはこれをどのような変数を取得しているlinker.onで認識することができませんでしたシンボルが存在することを意味...あなたはクラスStackを使用していることは、あなたの過負荷、および上記MyTempであること

+0

私のコードでどうやっているのか分からないので、混乱を避けるために投稿したときにStackのすべてのインスタンスをMyTempに変更しようとしました。しかし、ありがとう。 – Doug

1

を用心エラー また、std :: stackクラスが利用可能であるため、スタックでもチェックしてください。

関連する問題