2016-07-01 6 views
1

는 다음 사항을 고려 회원의 메소드 호출템플릿 전달은

당신이 상상할 수있는, has_my_method_callable_with_the_following_typestype가 호출 할 수있는 방법이있는 경우 나 확인할 수 있습니다 SFINAE 구조체의 일종이다,
template <typename type> class my_wrapper 
{ 
    type _; 

    template <typename... types, typename std :: enable_if <has_my_method_callable_with_the_following_types <type, types...> :: value> :: type * = nullptr> void my_method(types... items) 
    { 
    _.my_method(items...); 
    } 
}; 

그 유형들.

쉽게 알 수 있듯이 위의 예는 기본적으로 my_method에 대한 모든 호출을 _으로 전달합니다. 잘. 거의 모두입니다. my_type :: my_method 참조로 그것을 수용하면서 x 복사하여 함수에 전달 될 것처럼

class my_type 
{ 
    void my_method(int & x) 
    { 
    x++; 
    } 
}; 

my_wrapper <my_type> my_wrapped; 

int x; 
my_wrapped.my_method(x); 

은 분명히 위, 작동하지 않습니다 : 어떻게 내가 할 경우 발생합니다. 그래서 나는 궁금하다.이 문제를 해결할 방법이 있을까?

template <typename... types, typename std :: enable_if <has_my_method_callable_with_the_following_types <type, types & ...> :: value> :: type * = nullptr> void my_method(types & ... items) 
{ 
    _.my_method(items...); 
} 

을하지만 대칭 나는 말, 전달하고 문제가, 내가 참조하지 수 있지만 일부 my_type :: my_method(int x)에 의해 완벽하게 허용 될 수 int 리터럴을해야합니다 : 물론 나는 할 수있다.

이 문제를 해결하려면 어떻게해야합니까? my_wrapper <type> :: my_method에 대한 모든 통화를 type :: my_method으로 원활하게 전달하고 싶습니다.

해적주의 : 나는 상속을 사용할 수 없으므로 제안하지 마십시오!

T를 추론 할 때 말한다 언어에 특별한 규칙이있다 :이 어떻게 작동

template < 
    typename... types, 
    typename std :: enable_if <has_my_method_callable_with_the_following_types <type, types...> :: value> :: type * = nullptr 
> void my_method(types&&... items) 
{ 
    _.my_method(std::forward<types>(items)...); 
} 

: :)

+3

'완벽한 전달'을 찾고 있습니다 – lorro

답변

2

이 무엇 완벽한 전달 및 전달 참조가 도입 정확히입니다 T&& 구문에서 공제에 사용 된 인수가 U 유형의 시가 값이면 TU 대신 U&으로 추론됩니다.

매개 변수가 전달 참조 (T의 경우 T&&) 인 경우 인수는 lvalue 참조 (인수가 lvalue 인 경우) 또는 rvalue 참조 (인수가 rvalue). std::forward<T>은 적절한 경우 lvalue 또는 rvalue로 다시 캐스팅합니다.

+0

'_.my_method (std :: forward (items) ...)'및 '_.my_method (items ...)'를 호출하는 것의 차이점은 무엇입니까? '? –

+2

@MatteoMonti 명명 된 rvalue 참조가 lvalue임을 잊지 마십시오. 'my_method'가 rvalue 참조 (또는 값에 의한 이동 전용 타입)를 받아들이면'std :: forward'가없는 버전은 실패합니다. – Angew