2013-11-03 16 views
4

C++ 11의 전달 방법을 이해합니다.rvalue 인수에 대한 템플릿 유형 공제

template <class T> void foo(T &&) 

foo는 이제 lvalues와 rvalues를 모두 허용합니다.

내 문제는 foo를 더욱 오버로드 할 때입니다. 이 간단한 코드를 고려 : 내가 A <int> & (좌변) 객체 foo를 호출 할 경우

template <class T> class A {}; 

template <class T> void foo(T &&obj) {} 
template <class T> void foo(A<T> &&obj) {} 

int main() { 
    int i; 
    A<int> a; 
    foo(i); // calls foo(T &&) as I want 
    foo(a); // calls foo(T &&), but I want it to call foo(A<T> &&) 
    return 0; 
} 

를, 그것은 foo(T &&), 그리고 foo(A <T> &&)를 호출합니다. objA<T> 또는 아니지만, 내가 obj에서 A 메소드를 호출해야하므로이, 아주 아주 지저분한 코드를 생성하고, objT로 선언하고,하지 않은 경우 foo(T &&obj)의 정의에서, 나는 표준 및 사용자 정의 특성으로 구분 관리 A <T>. 선언을 재정렬하거나 lvalue 오버로드를 추가해도 문제가 해결되지 않습니다.

희망은 나 자신을 이해하게 만들었습니다. 문제를 해결하기 위해 간단한 코드를 제공했습니다. 나는 (boost::optional 유사) 사용자 정의 Optional <T> 클래스를 구현, 그리고 난 다른 Optional <T>, Optional <U>, T 또는 U 객체에서 Optional <T> 객체를 생성 (및 지정) 할 수 있어야합니다 나는 생성자에서이 문제를 가지고있다. 여기서 T은 생성 될 선택적 개체에 의해 보유되는 유형이고 UT으로 변환 가능한 다른 유형입니다.

감사합니다. 매개 변수 유형은 이력서 - 자격이 템플릿 매개 변수는 [temp.deduct.call]/3

[P 인 경우 함수 호출에 대한 템플릿 인수 공제 동안

+3

스택 오버플로 규칙의 전문성이 있는지 확인 : 영업 이익이 "이해"로 시작하면, 그들은하지 않습니다. 'A '과 같은 방식으로 작동하지 않는'T' 공제에 대해서는 특별한 것이 있습니다. –

+0

[이 예에서는] (http://ideone.com/jN2T2m)와 같이 원하는 오버로드를 직접 추가하는 것이 가장 쉽습니다. SFINAE를 사용하는 복잡한 회선 솔루션을 만들 수는 있지만 그 중 많은 이점이 있다고 생각하지 않습니다. –

+1

T는 범용 참조입니다. 반면에 A 은 평범한 오래된 rvalue 참조입니다. – aaronman

답변

6

는 "보편적 참조"에 대한 특별한 규칙은 적용 P는 CV-비정규 템플릿 파라미터에 r- 수치 참조는 인수가 A에, 타입 "좌변 참조 좌변 경우 파라미터 함수 템플릿 유형 및 A 인수의 형태]

인 형식 공제에 A 대신 사용됩니다. [예 :

template <class T> int f(T&&); 
template <class T> int g(const T&&); 
int i; 
int n1 = f(i); // calls f<int&>(int&) 
int n2 = f(0); // calls f<int>(int&&) 
int n3 = g(i); // error: would call g<int>(const int&&), which 
// would bind an rvalue reference to an lvalue 

-단부 예 마찬가지로

이러한 규칙, 파라미터 타입 A<T>&& 적용되지 할 . 그것은 "보편적 인 참조"가 아니라 순수히 rvalue-reference 유형입니다.당신이 할 수있는


당신이 A<T> -version이 (더 나은 경기)보다 전문화한다이 생성자 사이에 순위를 가지고 싶다면 :

  • 세 과부하 A<T> const&을 제공, A<T>& (감사합니다, Eric Niebler) 및 일반 버전
  • SFINAE를 사용하십시오. 매개 변수 T&& 두 개의 오버로드를 제공하고 T가 엄지 손가락 # 2의 A<T>
+1

'A const &'및'A '에'A &'에 세 번째 과부하가 필요합니다. &&'. 지저분 해. –

+0

@EricNiebler 오! 맞습니다. *보다 전문화 된 *는 필요한 변환을 고려한 후에만 타이 브레이커로 사용됩니다 (이 경우 'A const &'에 대한 한정어 변환 및 유형이' '인 lvalue 인수와 Exact Match 'T &&'함수를 위해). – dyp