2012-07-21 2 views
1

템플릿 매개 변수와 관련하여 템플릿 클래스에 [] 연산자를 오버로드하고 싶습니다. 그래서 같이 :C++ 템플릿 클래스 오버로드 [] 연산자

template< 
    typename T, 
    template<typename> class Property, 
    template<typename> class Key1, 
    template<typename> class Key2> 
class a_map 
{ 
public: 
    const Property<T>& operator[](const Key1<T>& k) const 
    { return _values[k.index()]; } 
    const Property<T>& operator[](const Key2<T>& k) const 
    { return _values[k.index()]; } 
protected: 
    std::vector<Property<T> > _values; 
}; 

그래서 같이이 클래스를 사용합니다 :

int main() 
{ 
    a_map<float, prop, key_a, key_b> pm; 
} 

는 기본적으로 나는 Key 유형에 대해 훨씬에 걱정하지 않고 _values 벡터 내부의 요소에 액세스 할 수 있어야합니다. 중요한 것은 회원이 index()입니다.

그러나 나는

error C2535: 'const Property &a_map::operator [](const Key1 &) const' : member function already defined or declared

비록 key_akey_b 이 totaly 다른 유형 클래스 템플릿입니다 다음과 같은 오류를 얻을.

내가 누락 된 항목이 있습니까? 컴파일러는 특정 상황에서 Key1<T>Key2<T>이 실제로 같은 유형 일 수 있음을 두려워합니까?

편집 이들은 내가 MVC++ 2008 컴파일러를 사용하고 편집 main

template<typename T> 
struct prop 
{ 
    T weight; 
    T height; 
}; 


template<typename T> 
class key_a 
{ 
public: 
    int index() { return _i; } 
private: 
    int _i; 
}; 

template<typename T> 
class key_b 
{ 
public: 
    int index() { return 3; } // Always return 3 

에 사용되는 클래스 템플릿입니다.

+2

'Key1'과'Key2'는 서로 다른 템플릿입니까? 'std :: vector'와'std :: list'를 테스트 등으로 시도해보십시오. –

+2

'key_a'와'key_b' - 타입?당신의 선언에 따르면'key_a'와'key_b'는 타입이 아닌 class * templates *이어야합니다. 2, 3 및 4 번째 템플릿 매개 변수를 * template-template * 매개 변수로 선언했습니다. 따라서 * 템플릿 *을 인수로 지정해야합니다. 'key_a'와'key_b'가 단순히 * types * 인 경우, 당신의 코드는 컴파일되지 않습니다. 테스트에서'key_a'와'key_b'가 무엇인지에 대한 구체적인 예를 제공하십시오. – AnT

+0

이것은 컴파일러 오류입니까, 링커 오류입니까? –

답변

0

이렇게 컴파일하면 ... Prop/K1/K2를 정의해야합니다.

#include <vector> 

template< 
    typename T, 
    template<typename> class Property, 
    template<typename> class Key1, 
    template<typename> class Key2> 
class a_map 
{ 
public: 
    const Property<T>& operator[](const Key1<T>& k) const 
    { return _values[k.index()]; } 
    const Property<T>& operator[](const Key2<T>& k) const 
    { return _values[k.index()]; } 
protected: 
    std::vector<Property<T> > _values; 
}; 

template <typename T> struct K1 { int index() const { return 0; } }; 
template <typename T> struct K2 { int index() const { return 0; } }; 
template <typename T> struct Prop { }; 

int main() 
{ 
    a_map<float, Prop, K1, K2> m; 
} 
+0

컴파일러는 사용되지 않는 템플릿 함수를 보지 않는다는 것을 기억하십시오. 주 함수는'operator [] '를 사용하지 않으므로이 두 루틴은 검사되지 않습니다. 이'K1 k1을 추가하십시오; – Adam

+0

@Adam : 물론, 일치하는 것이 없습니다. Tony의 예제에서'a_map'은'm [k1];에 인스턴스화됩니다. T = float'. 왜 'K1 '을 사용하려고합니까? – AnT

+0

@Tony Delroy 나는 당신의 정확한 코드를 시험해 보았고, 나는 내 눈이 멀었 기 때문에 내 컴파일러 MVSC 2008 – Iam

1

연산자 []는 인수 유형을 제외하고 모두 동일하므로 템플릿을 사용하지 않는 이유는 무엇입니까? a_map 템플릿 안에 당신이 const 객체

template<typename T> class key_a { 
public: 
    int index() const // <- `const` is necessary 
     { return _i; } 
private: 
    int _i; 
}; 

template<typename T> class key_b { 
public: 
    int index() const // <- `const` is necessary 
     { return 3; } 
}; 

그러나 그렇지 않으면 모든 컴파일을 통해 호출하고 나를 위해 잘 작동하기 때문에

template <typename TT> 
    const Property<T>& operator[](const TT& k) const 
    { 
     return _values[k.index()]; 
    } 
+0

왜냐하면 저는 키 유형을보다 잘 제어 할 수 있습니다. 컴파일러에서 특정 유형의 키를 허용하지 않기를 바랍니다. (Key1과 Key2 만 가능) – Iam

+1

@Iam : 그런 다음'enable_if'를 사용하십시오. 코드 복제에 대한 변명의 여지가 없습니다. –

+0

@CatPlusPlus : 차라리 "2 줄 이상으로 복잡하게 만들려는 변명의 여지가 없다"고 기대하고 싶지만 각자 자신의 생각대로 ... –

1

당신은 constindex() 함수를 선언해야합니다.


VS2010 컴파일러에서 시도한 것과 같은 오류가 발생합니다. 이것은 분명히 MSVC++ 컴파일러의 컴파일러 버그입니다. 템플릿 템플릿 인수 처리가 잘못 구현되었습니다.

내가이 기술

template< 
    typename T, 
    template<typename> class Property, 
    template<typename> class Key1, 
    template<typename> class Key2> 
class a_map 
{ 
public: 
    const Property<T>& operator[](const typename Key1<T>::self& k) const 
    { return _values[k.index()]; } 
    const Property<T>& operator[](const typename Key2<T>::self& k) const 
    { return _values[k.index()]; } 
protected: 
    std::vector<Property<T> > _values; 
}; 

에게 사용할 수 있었던 문제를 해결하려면

template<typename T> class key_a { 
public: 
    typedef key_a self; 
    int index() const { return _i; } 
private: 
    int _i; 
}; 

template<typename T> class key_b { 
public: 
    typedef key_b self; 
    int index() const { return 3; } 
}; 

이 세련 같이 키 템플릿을 정의하지만, 그것은 MSVC++ 컴파일러 제대로 작동하게하려면.