目的: STL のソース コードに精通しています。
最近、STL ソース コード分析の本を読みました。以前にも読んだことはありますが、これらのコードを自分で試したわけではないので、いくつかの概念は理解しているつもりかもしれませんが、実際には全然分かりません。。たとえば、次のコードは私自身の本から抜粋したものです。私は g++ コンパイラの ubuntu 18.04 バージョンを使用しています。コンパイラごとに異なる場合がありますが、STL ライブラリとその使用法をより深く理解しているだけです。
その中には、テンプレート クラスのフレンド関数とフレンド関数の関数オーバーロードの機能についても含まれます。コードとテスト結果はすぐ下に示されており、後ほど私自身の洞察を述べます。
#include<iostream>
#include<cstddef>
class alloc
{
};
template <class T, class Alloc=alloc, size_t BufSiz=0>
class deque
{
public:
deque(){
std::cout <<"deque"<<' ';}
};
template <class T, class Sequence>
class stack;
template <class T, class Sequence>
bool operator == (const stack<T, Sequence>& x, const stack<T, Sequence>& y);
template <class T, class Sequence>
bool operator < (const stack<T, Sequence>& x, const stack<T, Sequence>& y);
template <class T, class Sequence = deque<T>>
class stack
{
friend bool operator == (const stack<T, Sequence>& x, const stack<T, Sequence>& y)
{
std::cout << "operator == " << '\t';
return true;
}
friend bool operator < (const stack<T, Sequence>& x, const stack<T, Sequence>& y)
{
std::cout << "operator < " << '\t';
return true;
}
//friend bool operator== <T> (const stack&, const stack&);
//friend bool operator< <T> (const stack&, const stack&);
//friend bool operator== < >(const stack&, const stack&);
//friend bool operator< < >(const stack&, const stack&);
public:
stack(){
std::cout << "stack" <<std::endl;}
private:
Sequence c;
};
/*
template <class T, class Sequence>
bool operator == (const stack<T, Sequence>& x, const stack<T, Sequence>& y)
{
return std::cout <<"operator == " << '\t';
}
template <class T, class Sequence>
bool operator<(const stack<T, Sequence>& x, const stack<T, Sequence>& y)
{
return std::cout<<"operator < " << '\t';
}
*/
int main()
{
stack<int> x;
stack<int> y;
std::cout << (x==y) << std::endl;
std::cout << (x<y) <<std::endl;
}
上記のコードのテスト結果は次のとおりです。
テストはパスしていることがわかりますが、これらの関数の実装がコメントしたコードの外側にある場合はテストがパスしません。これは侯潔氏の本の内容と矛盾しており、コンパイラなど。詳細は次のとおりです。
friend bool operator== <T> (const stack&, const stack&);
こういう発言はいつも間違えるので後から確認しました。
したがって、従来の宣言方法を使用するようにしてください。同時に、上記で渡されたテンプレートなど、テンプレート内にコードを実装してみます。
これは私自身がテストした結果ですので、間違いがある場合は一緒に議論してください。
理解:
テンプレート クラスでは、フレンド関数は可能な限りクラス本体に実装する必要があります。