[c++] std :: decay는 무엇이며 언제 사용해야합니까?

존재하는 이유는 무엇입니까 std::decay? 어떤 상황에서 std::decay유용합니까?



답변

<joke> 방사성 std::atomic유형을 비 방사성 유형으로 붕괴시키는 데 사용됩니다 . </ joke>

N2609 는 제안한 논문이다 std::decay. 이 논문은 다음과 같이 설명합니다.

간단히 말해서, decay<T>::typeT가 배열 유형이거나 함수 유형에 대한 참조 인 경우를 제외하고 ID 유형 변환입니다. 이 경우 decay<T>::type함수에 대한 포인터 또는 포인터가 각각 생성됩니다.

동기 부여 예제는 C ++ 03입니다 std::make_pair.

template <class T1, class T2>
inline pair<T1,T2> make_pair(T1 x, T2 y)
{
    return pair<T1,T2>(x, y);
}

문자열 리터럴이 작동하도록하기 위해 값으로 매개 변수를 승인했습니다.

std::pair<std::string, int> p = make_pair("foo", 0);

참조로 매개 변수를 수락 T1하면 배열 유형으로 추론 된 다음 a 구성 pair<T1, T2>이 잘못됩니다.

그러나 분명히 이것은 비효율적 인 결과를 초래합니다. 따라서, 값별 decay전달이 발생할 때 발생하는 변환 세트를 적용하여 매개 변수를 참조로 효율적으로 사용할 수는 있지만 코드가 문자열 리터럴로 작동하는 데 필요한 유형 변환을 얻을 수 있어야합니다. 배열 유형, 함수 유형 등 :

template <class T1, class T2>
inline pair< typename decay<T1>::type, typename decay<T2>::type >
make_pair(T1&& x, T2&& y)
{
    return pair< typename decay<T1>::type,
                 typename decay<T2>::type >(std::forward<T1>(x),
                                            std::forward<T2>(y));
}

참고 : 이것은 실제 C ++ 11 make_pair구현 이 아닙니다 . C ++ 11 make_pairstd::reference_wrappers 를 풉니 다 .


답변

템플릿 유형의 매개 변수를 사용하는 템플릿 함수를 처리 할 때 일반적으로 범용 매개 변수가 있습니다. 범용 매개 변수는 거의 항상 한 종류 또는 다른 종류의 참조입니다. 그들은 또한 const-volatile 자격을 갖추고 있습니다. 따라서 대부분의 유형 특성은 예상대로 작동하지 않습니다.

template<class T>
void func(T&& param) {
    if (std::is_same<T,int>::value)
        std::cout << "param is an int\n";
    else
        std::cout << "param is not an int\n";
}

int main() {
    int three = 3;
    func(three);  //prints "param is not an int"!!!!
}

http://coliru.stacked-crooked.com/a/24476e60bd906bed

해결책은 다음과 std::decay같습니다.

template<class T>
void func(T&& param) {
    if (std::is_same<typename std::decay<T>::type,int>::value)
        std::cout << "param is an int\n";
    else
        std::cout << "param is not an int\n";
}

http://coliru.stacked-crooked.com/a/8cbd0119a28a18bd


답변