2011-08-01 6 views
2

これは、このテンプレートのすぐ下に配置された質問とは少し異なります。 2つのテンプレートパラメータを持つコンテナクラスがあるとします。最初の型は型、2番目はコンテナのサイズです。複数のテンプレートパラメータのうちの1つだけを必要とするクラス定義を含むテンプレートコンテナ

ここでは、コンテナの格納サイズが異なる複数のコンテナがあります。本質的には、コンテナの機能(すべての公共のもの、とにかく)は本当に気にするだけですT; Nは、ローカルストレージを割り当てるためにのみ使用されます(アロケータは、Nで十分でない場合に使用されます)。

私が持っている問題を紹介する簡単な実装例をまとめました。

#include <iostream> 

template <typename T, size_t N = 10> 
class TestArray 
{ 
public: 
    T Local[N]; 

    class Iterator 
    { 
    public: 
     T* Array; 
     int Index;  

     Iterator() : Array(NULL), Index(-1) { } 
     Iterator(T* _array, int _index) : Array(_array), Index(_index) { } 

     bool operator == (const Iterator& _other) const 
     { 
      return _other.Index == Index && _other.Array == Array; 
     } 

     bool operator != (const Iterator& _other) const 
     { 
      return !(*this == _other); 
     } 

     template <size_t _N> 
     Iterator& operator = (const typename TestArray<T, _N>::Iterator &_other) 
     { 
      Array = _other.Array; 
      Index = _other.Index; 

      return *this; 
     } 

     void Next() { ++Index; } 
     void Prev() { --Index; } 

     T& Get() { return Array[Index]; } 
    }; 

    T& operator [] (const int _index) { return Local[_index]; } 

    Iterator Begin() { return Iterator(Local, 0); } 
    Iterator End() { return Iterator(Local, N); } 

    template <size_t _N> 
    void Copy(const TestArray<T, _N> &_other, int _index, int _count) 
    { 
     int i; 

     for (i = 0; i < _count; i++) 
      Local[_index + i] = _other.Local[i]; 
    } 
}; 

これは本当に2つの問題です。前に投稿した最初の部分:Template container with multiple template parameters interacting with other template containers with a different template parameter。第二部では、私は次のようにそれを使用しようとしている:ここで

int main() { 

    TestArray<int> testArray1; 
    TestArray<int, 25> testArray2; 

    TestArray<int>::Iterator itr; 

    itr = testArray1.Begin(); 

    for (itr = testArray1.Begin(); itr != testArray1.End(); itr.Next()) 
    { 
     itr.Get() = itr1.Index; 
    } 

    testArray2.Copy(testArray1, 0, 10); 

    for (itr = testArray2.Begin(); itr != testArray2.End(); itr.Next()) 
    { 
     std::cout << itr.Get() << std::endl; 
    } 

    return 0; 
} 

はIDEONEリンクです:http://ideone.com/GlN54

のgcc-4.3.4でコンパイルされたとき、私は以下の取得:

VS2010で
prog.cpp: In function ‘int main()’: 
prog.cpp:67: error: no match for ‘operator=’ in ‘itr = testArray2.TestArray<T, N>::Begin [with T = int, unsigned int N = 25u]()’ 
prog.cpp:10: note: candidates are: TestArray<int, 10u>::Iterator& TestArray<int, 10u>::Iterator::operator=(const TestArray<int, 10u>::Iterator&) 
prog.cpp:67: error: no match for ‘operator!=’ in ‘itr != testArray2.TestArray<T, N>::End [with T = int, unsigned int N = 25u]()’ 
prog.cpp:19: note: candidates are: bool TestArray<T, N>::Iterator::operator!=(const TestArray<T, N>::Iterator&) const [with T = int, unsigned int N = 10u] 

、私は次を得る:

1>------ Build started: Project: testunholytemplatemess, Configuration: Debug Win32 ------ 
1> main.cpp 
1>c:\users\james\documents\testproj\testunholytemplatemess\testunholytemplatemess\main.cpp(67): error C2679: binary '=' : no operator found which takes a right-hand operand of type 'TestArray<T,N>::Iterator' (or there is no acceptable conversion) 
1>   with 
1>   [ 
1>    T=int, 
1>    N=25 
1>   ] 
1>   c:\users\james\documents\testproj\testunholytemplatemess\testunholytemplatemess\main.cpp(34): could be 'TestArray<T>::Iterator &TestArray<T>::Iterator::operator =(const TestArray<T>::Iterator &)' 
1>   with 
1>   [ 
1>    T=int 
1>   ] 
1>   while trying to match the argument list '(TestArray<T>::Iterator, TestArray<T,N>::Iterator)' 
1>   with 
1>   [ 
1>    T=int 
1>   ] 
1>c:\users\james\documents\testproj\testunholytemplatemess\testunholytemplatemess\main.cpp(67): error C2679: binary '!=' : no operator found which takes a right-hand operand of type 'TestArray<T,N>::Iterator' (or there is no acceptable conversion) 
1>   with 
1>   [ 
1>    T=int, 
1>    N=25 
1>   ] 
1>   c:\users\james\documents\testproj\testunholytemplatemess\testunholytemplatemess\main.cpp(19): could be 'bool TestArray<T>::Iterator::operator !=(const TestArray<T>::Iterator &) const' 
1>   with 
1>   [ 
1>    T=int 
1>   ] 
1>   while trying to match the argument list '(TestArray<T>::Iterator, TestArray<T,N>::Iterator)' 
1>   with 
1>   [ 
1>    T=int 
1>   ] 

私はIterator& operator = WOUを考えましたこの代入演算子は動作するはずですが、明らかにそうではありません。多分私は太っているかもしれませんが、私はここで正しい解決方法を決定することに失敗しています。誰にも何か提案はありますか?

+0

Big Threeが必要です!あなたはデフォルトコンストラクタと代入オーバーロードを持っていますが、Iteratorにコピーコンストラクタはありません! –

+0

@Bob彼はデフォルトのコピーコンストラクタを使用しますか? –

+0

@VJo、Big Threeが重要であることに留意して、それは問題の答えではありません。このインスタンスのデフォルトのコピーコンストラクタは問題ありませんが、Big Threeの法則に従うことは常に良い習慣です。 –

答えて

6

TestArray<T, 1>TestArray<T, 2>異なるタイプであるのでTestArray<T, 1>::IteratorTestArray<T, 2>::Iteratorあります。割り当ては機能しません! (あなたのitrtestArray2.Begin()のタイプとは異なるタイプです)

全体の構成は私にとって非常に疑わしいと思われます - これは本当に必要ですか?あなたは何を達成しようとしていますか? std::arrayを見ましたか?


更新:

for (itr.operator=<int,25>(testArray2.Begin()); 
     itr.operator!=<int,25>(testArray2.End()); 
     itr.Next()) 
    { 
    std::cout << itr.Get() << std::endl; 
    } 

私はパラメータが引数から推論することができない理由はまったくわからないんだけど、私は良いことを楽しみにしています:それはあなたが明示的にテンプレートパラメータを供給した場合に動作します説明 - その間、私は完全なコードon Ideoneを入れましたが、そこではコンパイルされませんでしたが、私のGCC 4.6.1ではそうです。

+0

私は、オーバーライドされた 'operator ='は異なるタイプ間の代入を可能にすると仮定していました。基になる型は 'TestArray 'ですが、オーバーライドされた演算子を使用して割り当てることができます。 – James

+0

ここにIDEOneまたはその答えがあります:http://ideone.com/lnJE7 –

+0

エラーメッセージは、コンパイラが同じタイプを探していることを示しています。正しいコードを教えてください。 '!='演算子は間違いなくテンプレート化されていません! –

2

デフォルトのテンプレート引数を使用すると、コンパイラは自動的にデフォルトを自動的に提供しますが、依然としてテンプレート定義の一部です。あなたの場合、TestArray<int>TestArray<int, 10>と同じです。 TestArray<T, N> and TestArray<T, M>の間で相互運用したい場合は、おそらくテンプレート関数を使用したいと思うでしょう。

編集:私が思い付くことができた唯一の解決策は、イテレータを自分のクラスに分割して、それが望ましいものとして機能することです。私があなたに言うことができないのは、それがうまくいかない理由です。テンプレート拡張の可能性のある内部クラスを探すのは好きではないので、私の推測はそうです。いずれにしても、ここで私がしたことがあります。

#include <iostream> 

template <typename T, size_t N = 10> class TestArray; 

template<typename T, size_t N> 
    class TIterator 
    { 
    public: 
     T* Array; 
     int Index;  

     TIterator() : Array(NULL), Index(-1) { } 
     TIterator(T* _array, int _index) : Array(_array), Index(_index) { } 

     bool operator == (const TIterator& _other) const 
     { 
    return _other.Index == Index && _other.Array == Array; 
     } 

     bool operator != (const TIterator& _other) const 
     { 
    return !(*this == _other); 
     } 

     TIterator& operator = (const TIterator& _other) { 
    Array = _other.Array; 
    Index = _other.Index; 
    return *this; 
     } 

     template <size_t M> 
     bool operator == (const TIterator<T, M>& _other) const 
     { 
    return _other.Index == Index && _other.Array == Array; 
     } 

     template <size_t M> 
     bool operator != (const TIterator<T, M>& _other) const 
     { 
    return !(*this == _other); 
     } 

     template< size_t M> 
     TIterator& operator = (const TIterator<T, M>& _other) { 
    Array = _other.Array; 
    Index = _other.Index; 
     } 

     void Next() { ++Index; } 
     void Prev() { --Index; } 

     T& Get() { return Array[Index]; } 
    }; 



template <typename T, size_t N> 
class TestArray 
{ 
public: 
    T Local[N]; 

    typedef TIterator<T, N> Iterator; 

    T& operator [] (const int _index) { return Local[_index]; } 

    Iterator Begin() { return Iterator(Local, 0); } 
    Iterator End() { return Iterator(Local, N); } 

    template <size_t _N> 
    void Copy(const TestArray<T, _N> &_other, int _index, int _count) 
    { 
    int i; 

    for (i = 0; i < _count; i++) 
     Local[_index + i] = _other.Local[i]; 
    } 
}; 
int main() { 

    TestArray<int> testArray1; 
    TestArray<int, 25> testArray2; 
    TestArray<double, 10> testArray3; 

    TestArray<int>::Iterator itr; 

    itr = testArray1.Begin(); 

    for (itr = testArray1.Begin(); itr != testArray1.End(); itr.Next()) 
    { 
     itr.Get() = itr.Index; 
    } 

    testArray2.Copy(testArray1, 0, 10); 


    for (itr = testArray2.Begin(); itr != testArray2.End(); itr.Next()) 
    { 
     std::cout << itr.Get() << std::endl; 
    } 


    return 0; 
} 

注、私はTIteratorはちょうどそれが働いたことを示すために、それは技術的に第2のテンプレート引数を使用していないにもかかわらず、両方の型引数を使用していました。

+0

これはテンプレート 'operator ='で達成しようとしていたものですが、それでも私の方法には不一致があるようです。 – James

+0

更新していただきありがとうございます。これは法的な構造だと私たちに伝えていると思いますが、内部クラスであるためコンパイラはボールを演奏しません。 – James

関連する問題