2011-08-01 1 views
2

이것은이 바로 아래 배치 된 질문과 약간 다릅니다. 두 개의 템플릿 매개 변수가있는 컨테이너 클래스가 있다고 가정합니다. 첫 번째 매개 변수는 형식이고 두 번째 매개 변수는 컨테이너의 크기입니다.여러 템플릿 매개 변수 중 하나만 필요로하는 클래스 정의가 포함 된 템플릿 컨테이너

이제 컨테이너 크기가 다른 여러 컨테이너가 있습니다. 본질적으로 컨테이너 기능 (모든 공개 기능, 어쨌든)은 실제로는 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]; 
    } 
}; 

이것은 실제로 두 부분으로 된 질문입니다. 이전에 게시 한 첫 번째 부분은 Template container with multiple template parameters interacting with other template containers with a different template parameter입니다.

: http://ideone.com/GlN54

GCC-4.3.4, 나는 다음과 같은 얻을 컴파일 : 여기

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 링크입니다 : 두 번째의 경우, 나는 다음과 같이 사용하려고 해요
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 = 올릴 때 생각 :
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] 

는 VS2010에서, 나는 다음을 얻을 이 대입 연산자가 작동해야하지만 분명히 그렇게하지 않도록하십시오. 아마 나는 두꺼운지만 정확한 해결책을 결정하는 데 실패하고 있습니다. 누구든지 어떤 제안이 있습니까?

+0

Big Three가 필요합니다! 기본 생성자와 할당 오버로드가 있지만 Iterator에 복사 생성자가 없습니다! –

+0

@Bob 그는 기본 복사 생성자를 사용합니까? –

+0

@VJo, 빅 3가 중요하다는 것을 알면 문제의 해답이 아닙니다. 이 인스턴스의 기본 복사 생성자는 괜찮지 만 빅 3의 법칙을 따르는 것이 좋습니다. –

답변

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> 사이에서 상호 운용하려면 템플릿 함수를 사용하는 것이 좋습니다.

편집 : 내가 생각해 낼 수 있었던 유일한 해결책은 iterator를 자신의 클래스로 분리 한 다음 원하는대로 작동시키는 것입니다. 내가 말할 수없는 것은 그것이 효과가없는 이유입니다. 내 생각 엔 가능한 템플릿 확장을위한 내부 클래스 검색을 좋아하지 않기 때문입니다.어느 쪽이든, 내가 한 일이 여기있다.

#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 사용 두 형태 인수했다.

+0

맞아, 나는'operator ='템플릿으로 성취하려고 시도했지만, 여전히 내 방법에 동의하지 않는 것 같다. – James

+0

감사합니다. 이것이 합법적 인 구조이지만 내부 클래스이기 때문에 컴파일러는 공을 사용하지 않는다고 말하고 있습니다. – James

관련 문제