2013-09-02 3 views
0

내가 코드의 두 조각이 있습니다C++ 11 템플릿 인스턴스화 오류

1)

template< class T > 
    auto min(T a, T b) -> decltype(a) 
    { 
     return a < b ? a : b; 
    } 




int main() 
{ 
    struct A{}; 
    auto x = min(2, 3) ;// success 

    auto a = A{}; 
    auto b = A{}; 
    auto c = min(a,b);// here is error  
} 

http://ideone.com/cXgnPy

그리고 2)

template< class T > 
    auto min(T a, T b) ->decltype(a<b, a) 
    { 
     return a < b ? a : b; 
    } 



int main() 
{ 
     struct A{}; 
     auto x = min(2, 3) ;// success 
     auto a = A{}; 
     auto b = A{}; 
     auto c = min(a,b);// here is another error  
} 

http://ideone.com/Rfs4Lv

첫 번째 및 두 번째 대소 문자의 다른 오류는 무엇입니까? 어느 것이 더 낫습니까?

UPD : '분'구현은 더 나은 무엇입니까? INT가

+1

1) 받고있는 오류에 대해서는 언급하지 않았습니다. 2) 예제 코드에서 볼 수 있듯이 struct에 대해 operator <가 정의되어 있지 않기 때문에 기꺼이 할 것입니다. – Rapptz

+0

구조체 A에 대해'a nijansen

+3

** 'auto' 키워드 **를 남용하지 마십시오.함수'min()'은 같은 타입의 인스턴스와 비교되므로, 후행 리턴 타입을 사용할 이유가 없습니다. 리턴 타입은 분명히'T'입니다. 또한'decltype (a Manu343726

답변

1

구조체 (A)는 컴파일러는 아마 당신이 말했듯이, 문제가 피연산자 AA에 대한 operator<에 대한 일치하지 않는다는 것이다 정의 연산자 <하지 않습니다. int는 내장이 연산자를 가지고 있지만, 당신은 당신의 자신의 클래스에 대한 하나를 직접 선언해야합니다

struct A 
{ 
    A(int a) : a(a) {} 

    bool operator<(A const & rhs) 
    { 
     return a < rhs.a; 
    } 

    int a; 
}; 

다음 min(A(1), A(2)) 유효한 호출된다. 문제는 제공 한 두 코드 스 니펫에 대해 동일합니다.

min 구현은 더 나은 무엇입니까?

나도 선택하지 않을 것입니다. 첫째, 반환 형식의 후반 결정에 대한 필요가 없습니다, 당신은 단지

template <typename T> 
T min(T a, T b) 
{ return a < b ? a : b; } 

가 할 수 있었던 두 번째 코드는 더 악화되는 동일한 코드를 난독된다. 또한 <algorithm> 헤더에 std::min이 있습니다.

1

내 의견에 말했듯이 : 가 자동 키워드 아닌 학대를 수행합니다. 함수 min()은 동일한 유형의 두 인스턴스를 비교하므로 후행 반환 유형을 사용할 이유가 없습니다. 반환 유형은 분명히 T입니다.
seond 버전은 쉼표 연산자를 사용합니다.이 연산자는 첫 번째 피연산자를 계산하고 버리고 두 번째 피연산자를 계산하여 반환합니다. 이 경우처럼 decltype을 엔티티 대신 표현식과 함께 사용하면 표현식의 리턴 유형을 리턴합니다. 따라서이 버전은 T 대신 T&을 반환합니다.

그래서 대답은 : 번째 버전이 더 나은, 사본을 피할 수 있기 때문이다. 그러나 두 버전 모두 trirty 반환 유형을 사용하는 불행하고 불필요한 경우입니다. 좋은 접근 방법은 T을 반환하는 것입니다.

template<typename T> 
T& min(const T& lhs , const T& rhs) 
{ 
    return lhs < rhs ? lhs : rhs; 
} 
+0

@LucDanton 쉼표 연산자가 아니고'a' (예를 들어't')로 평가되지 않았다면이게 뭐죠? 귀하의 예를 들어 나를 당황하게 : – Manu343726

+0

[너무 많은 단어] (http://stackoverflow.com/questions/9467791/decltypefun-is-strange/9469979#9469979),'decltype' 두 가지 중 하나를 수행 할 수 별개의 것들 - 엔티티의 유형 또는 표현식의 유형을 검사하십시오. 이 경우 두 가지 용도가 서로 다른 두 가지 결과를내는 두 가지 결과가 발생합니다. –

+0

[참조] (http://en.cppreference.com/w/cpp/language/operator_other)는 다음과 같이 말합니다. "쉼표 연산자의 반환 유형 및 값 범주는 정확히 반환 유형이며 두 번째 피연산자의 값 범주입니다 , E2. "* 첫 번째 사례와 두 번째 사례의 차이는? – Manu343726