2011-10-17 8 views
1

지능 운영자 < <가 (코드 참조) GCC 4.6.1 내가 오류 다음 얻고로 컴파일하는 동안 정의 된이 클래스 없습니다 : '연산자 < <'에 대한 일치의 'std :: cout < < a'. 무슨 일이야? Best_Fit의 모습누락 된 연산자 <<하지만이

template<class Int_T = int, typename Best_Fit<Int_T>::type Min_Range = std::numeric_limits<Int_T>::min(), 
          typename Best_Fit<Int_T>::type Max_Range = std::numeric_limits<Int_T>::max()> 
class Int 
{ 
Int_T data_; 

Int_T get_data()const 
{ 
return data_; 
} 

}; 
//Here is this operator defined 
template<class Int_T> 
std::ostream& operator<<(std::ostream& out, const Int<Int_T, Best_Fit<Int_T>::type, Best_Fit<Int_T>::type>& obj) 
{ 
    out << obj.get_data(); 
    return out; 
} 

:

#ifndef BEST_FIT_H_INCLUDED 
#define BEST_FIT_H_INCLUDED 


struct Signed_Type 
{ 
    typedef long long type; 
}; 

struct Unsigned_Type 
{ 
    typedef unsigned long long type; 
}; 

template<bool Cond, class First, class Second> 
struct if_ 
{ 
    typedef typename First::type type; 
}; 

template<class First, class Second> 
struct if_<false,First,Second> 
{ 
    typedef typename Second::type type; 
}; 

template<class Int_T> 
struct Best_Fit 
{//evaluate it lazily ;) 
    typedef typename if_<std::is_signed<Int_T>::value,Signed_Type,Unsigned_Type>::type type; 
}; 

#endif // BEST_FIT_H_INCLUDED 

편집 :

#include <iostream> 
int main(int argc, char* argv[]) 
{ 
    Int<signed char,1,20> a(30); 

    cout << a; 
} 
+0

당신이 예와를 제공 할 수 있습니다 (운영자가 클래스 내부에 정의되어있는 경우 당신은 또한 외부를 선언하기로 결정 --unless 다음은 ADL을 통해 액세스 할 수 있다는 사실 등) 몇 가지 다른 차이가 있습니다 본관? –

+0

@VJo 편집, OP – smallB

+0

참조 그게 행복한 템플릿 마법입니다. 표준 숫자 형식을 래핑합니다. 그렇지 않습니까? 그것이 비밀이 아니라면, 당신의 목표는 무엇입니까? 왜 이런 짓을하는? – Septagram

답변

2

귀하의 템플릿 세 가지 인수, 유형 및 알려진 가장 적합한 유형의 두 상수를 가지고 있지만 템플릿이 operator<< 인 템플릿의 인스턴스화는 세 개의 유형으로 이루어집니다. .

내가 일반적으로 클래스 템플릿의 연산자 오버로드를 추천

는 클래스 정의이 특정 이유로 (그 맥락에서 무료로 함수를 정의 friend 사용) 내부에 정의되어

template<class Int_T = int, typename Best_Fit<Int_T>::type Min_Range 
            = std::numeric_limits<Int_T>::min(), // constant! 
          typename Best_Fit<Int_T>::type Max_Range 
            = std::numeric_limits<Int_T>::max() // constant! 
     > 
class Int 
//... 
template<class Int_T> 
std::ostream& operator<<(std::ostream& out, 
         const Int<Int_T, 
            Best_Fit<Int_T>::type, // type! 
            Best_Fit<Int_T>::type // type! 
         >& obj) 
,이 클래스 내부에 오른쪽 종류를 얻을 수 사소한 템플리트 및 외부에서 쉽게 실패 할 수 있습니다.

template<class Int_T = int, typename Best_Fit<Int_T>::type Min_Range 
            = std::numeric_limits<Int_T>::min(), // constant! 
          typename Best_Fit<Int_T>::type Max_Range 
            = std::numeric_limits<Int_T>::max() // constant! 
     > 
class Int { 
    friend     // allows you to define a free function inside the class 
    std::ostream& operator<<(std::ostream& out, 
          Int const & obj) { // Can use plain Int to refer to this 
                // intantiation. No need to redeclare 
                // all template arguments 
     return out << obj.get_data(); 
    } 
}; 
+0

그래서 무엇을 제안 하시겠습니까? – smallB

+0

그래서 당신이 말하는 것은 그것을 반원으로서 선언해야한다는 것입니다. 그러나 그것을 "자유로운"fnc로 선언 할 수있는 방법이 있습니까? – smallB

+0

답변을 편집했습니다. 가장 간단한 방법은 클래스 범위 내에 연산자를 정의하는 것입니다. 또는 템플릿을 수정 해 볼 수 있습니다. 시도하지 않았으므로 보증하지 않습니다 :'template :: type Min_Range, typename Best_Fit :: type Max_Range> std :: ostream & operator << (std :: ostream & o, Int const & obj) {...' –