2017-12-18 8 views
5

은 C++에서 템플릿 메타 프로그래밍, 나는 종종 다음과 같은 무언가로 실행하면 : 나는 반환 형식에 std::decay 같은 것을 사용한다 알고차이는 remove_reference

template <typename T> 
S<T> make_wrapper(T&& t) { return S<T>(std::forward<T>(t)); } 

하지만, 왜 std::remove_reference도 작동하지 않을까요? 여기의 차이점은 무엇입니까? std::remove_cvref은 어떨까요?

+5

무엇이'T '인지에 따라 [부식은 더 많이 할 수 있습니다] (http://en.cppreference.com/w/cpp/types/decay). –

+5

그들에 대해 읽으려고 했습니까? 예를 들어 [이'std :: decay' 참조] (http://en.cppreference.com/w/cpp/types/decay)와 [이'std :: remove_reference' 참조] (http : //en.cppreference .com/w/cpp/types/remove_reference). –

답변

4

참조를 삭제하면 constvolatile이 남습니다. 그것이 당신이 원하는 것이라면, 그것은 충분할 것입니다.

대부분의 부식은 cvref를 제거하지만 함수 유형과 배열 유형을 포인터로 변환하지 않습니다.

붕괴는 배열의 복사본이나 배열에 struct을 합리적으로 저장할 수있는 방식으로 형식을 변환하거나 함수에서 반환하거나 함수로 전달합니다.

8

는 CV-규정자가 제거됩니다 예를

#include <type_traits> 

int main() 
{ 
    static_assert(std::is_same_v< 
     std::decay_t<const int&>, 
     std::remove_reference_t<const int&> 
    >); // int != const int 
} 

std::decay에 대한 고려, remove_reference은하지 않습니다. 그것은 단지 형식의 "참조"부분을 제거합니다. reference에서

:

은 좌변 투를 rvalue는 타입 T에 암시 적 변환 배열 포인터로, 그리고 함수에 포인터, 이력서 - 예선을 제거 적용하고 를 정의 결과 유형을 구성원 유형 정의 유형으로 사용하십시오.

따라서 std::decaystd::remove_reference보다 훨씬 더 형식 변환을 수행합니다.

판매용 C++ 20 remove_cvref에서 remove_cv, remove_volatile 같이 수행 decay 가능한 변형들의 집합의 부분을 선택 또는 수행 뉘앙스 애플리케이션 추가 유형 수정있다.

+0

'std :: remove_cvref'로 충분합니까? –

+1

@Nex ': 아니오. [docs] (http://en.cppreference.com/w/cpp/types/decay)를 읽는 데는 실제로 2 분 밖에 걸리지 않습니다. –

+0

@ 넥스 '어쩌면 당신은 또한'std :: invoke'의 사용을 고려해야 할 것입니다. – Jodocus