2017-04-03 1 views
1

전달 참조로 std::aligned_storage_t 매개 변수를 허용하고 reinterpret_cast을 다른 유형으로 변환하여 사용자에게 반환하는 코드가 있습니다.클래스에 대한 참조를 다른 유형으로 전달

template <typename AlignedStorageType, typename TypeToReturnAs> 
decltype(auto) forward_as_another_type(AlignedStorageType&& storage) { 
    return *reinterpret_cast<TypeToReturnAs*>(&storage); 
} 

반환 유형에 storage이있는 참조 유형을 유지하는 좋은 방법이 있습니까? 예를 들어 저장 장치가 rvalue 참조 인 경우 반환 유형이 rvalue 참조가되기를 원합니다.

+0

std :: move에서와 같이'typename remove_reference :: type &&'의 반환 값이 도움이 될까요? –

답변

3

먼저 템플릿 매개 변수를 뒤집습니다. 당신이 기본적으로 원하는 것은 조건부 식을 캐스팅하는 것입니다

template <typename TypeToReturnAs, typename AlignedStorageType> 
decltype(auto) forward_as_another_type(AlignedStorageType&& storage) { 
    return *reinterpret_cast<TypeToReturnAs*>(&storage); 
} 

다음 : 당신은 AlignedStorageType 추론 할 다른 하나는 명시 적으로 지정해야합니다. AlignedStorageType&&X&& 인 경우 TypeToReturnAs&&으로 전송하고 싶습니다. X& 인 경우 TypeToReturnAs&으로 표시됩니다. X const& 인 경우 TypeToReturnAs const&으로 지정합니다. 당신이 할 수있는, 당신은 단지 일회성으로 이것을 사용하는 경우, 또는

template <typename TypeToReturnAs, typename AlignedStorageType> 
decltype(auto) forward_as_another_type(AlignedStorageType&& storage) { 
    using R = match_reference_t<AlignedStorageType&&, TypeToReturnAs>; 
    return static_cast<R>(*reinterpret_cast<TypeToReturnAs*>(&storage)); 
} 

: 다음

template <class T, class U> struct match_reference; 
template <class T, class U> struct match_reference<T&, U>  { using type = U&; }; 
template <class T, class U> struct match_reference<T const&, U> { using type = U const&; }; 
template <class T, class U> struct match_reference<T&&, U>  { using type = U&&; }; 
template <class T, class U> using match_reference_t = typename match_reference<T,U>::type; 

그리고 :

우리는 기준에 맞게 유형의 특성을 추가 할 수 있습니다 단지 조건부로 그 로직을 작성 :

template <typename TypeToReturnAs, typename AlignedStorageType> 
decltype(auto) forward_as_another_type(AlignedStorageType&& storage) { 
    using R = std::conditional_t< 
     std::is_lvalue_reference<AlignedStorageType>::value, 
     TypeToReturnAs&, 
     TypeToReturnAs&&>; 
    return static_cast<R>(*reinterpret_cast<TypeToReturnAs*>(&storage)); 
} 

나 :

using R = std::conditional_t< 
     std::is_lvalue_reference<AlignedStorageType>::value, 
     TypeToReturnAs&, 
     TypeToReturnAs>; 
    return std::forward<R>(*reinterpret_cast<TypeToReturnAs*>(&storage)); 
+0

감사합니다. 이것은 대단하다! 나는 AlignedStorageType이 내 코드에서 추론되도록 의도했다. 나는 단지 커스텀 특성을 만드는 것 이외의 다른 방법이 있을지 궁금했다. – Curious

+0

마지막 예제에서'std :: conditional_t'에 대한 세 번째 매개 변수가'TypeToReturnAs &&'가 아닌'TypeToReturnAs'인지 설명 할 수 있습니까? – Curious

+0

@Curious'forward '는'T &&'를 돌려주기 때문에 어느 쪽이든 마찬가지입니다. 이것은 조금 더 짧아서'forward'의 일반적인 사용법에 더 잘 맞습니다 ('std :: forward (x)'를 쓰지 마세요). – Barry

관련 문제