c++ - 사용법 - 유니크 포인터




make_unique 및 완벽한 전달 (4)

표준 C ++ 11 라이브러리에 std::make_unique 함수 템플릿이없는 이유는 무엇입니까? 나는 찾는다.

std::unique_ptr<SomeUserDefinedType> p(new SomeUserDefinedType(1, 2, 3));

약간 자세한. 뒤에 오는 것 매우 좋지 않 ㄹ 은가?

auto p = std::make_unique<SomeUserDefinedType>(1, 2, 3);

이것은 new 잘 숨기고 한 번만 타입을 언급합니다.

어쨌든, 여기 make_unique 구현에 대한 나의 시도가있다.

template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

컴파일하는 데 std::forward 자료를 얻는 데 꽤 오래 걸렸지 만, 그것이 맞는지 확실하지 않습니다. 그렇지? 정확히 std::forward<Args>(args)... 의미는 무엇입니까? 컴파일러는 무엇을 만드나요?


C ++ 11에서는 ... (템플릿 코드에서) "팩 확장"에도 사용됩니다.

요구 사항은 확장되지 않은 매개 변수 팩을 포함하는 식의 접미사로 사용하고 팩의 각 요소에 식을 적용하기 만하면됩니다.

예를 들어, 귀하의 예제를 구축 :

std::forward<Args>(args)... -> std::forward<int>(1), std::forward<int>(2),
                                                     std::forward<int>(3)

std::forward<Args...>(args...) -> std::forward<int, int, int>(1,2,3)

후자는 내가 생각하는 부정확하다.

또한 인수 팩은 확장되지 않은 함수에 전달 될 수 없습니다. 템플릿 매개 변수 팩이 확실하지 않습니다.


C ++ 표준화위원회 의장 인 Herb Sutter는 자신의 blog 다음과 같이 썼습니다.

C ++ 11에는 make_unique 가 포함되지 않았 make_unique 부분적으로는 감독이며 앞으로는 거의 추가 될 것입니다.

그는 또한 OP가 제공 한 것과 동일한 구현을 제공합니다.

편집 : std::make_unique 이제 C++14 일부입니다.


Stephan T. Lavavej의 구현에 영감을 얻어, 배열 범위를 지원하는 make_unique를 가지고 있으면 좋을지도 모른다고 생각합니다 . github 에 대한 의견을 듣고 싶습니다. 이 작업을 수행 할 수 있습니다.

// create unique_ptr to an array of 100 integers
auto a = make_unique<int[100]>();

// create a unique_ptr to an array of 100 integers and
// set the first three elements to 1,2,3
auto b = make_unique<int[100]>(1,2,3); 

아무 것도 자신의 도우미 작성을 멈추지는 않지만 라이브러리에서 make_shared<T> 를 제공하는 주된 이유는 shared_ptr<T>(new T) 와는 다른 내부 유형의 공유 포인터를 실제로 생성한다는 것입니다. 할당 된, 그리고 전용 도우미 없이는 이것을 달성 할 수있는 방법이 없습니다.

반면 make_unique 래퍼는 new 표현을 둘러싼 단순한 문법적 설탕이므로 눈에 즐거워 보일 수도 있지만 테이블에 new 것을 가져 오지는 않습니다. 수정 : 이것은 사실이 아닙니다 : new 표현식을 감싸기위한 함수 호출은 예를 들어 함수를 호출 할 때 예외 안전을 제공합니다. void f(std::unique_ptr<A> &&, std::unique_ptr<B> &&) . 서로에 대해 순서가 지정되지 않은 두 개의 원시 new 를 가짐으로써 하나의 새로운 표현식이 예외로 인해 실패하고 다른 하나의 표현식이 자원을 누설 할 수 있음을 의미합니다. 표준에 make_unique 가없는 make_unique 는 다음과 같습니다. 그냥 잊어 버렸습니다. (이 경우가 발생합니다. 표준 있어야하지만에도 표준 std::cbegin 없습니다.)

또한 unique_ptr 은 어떻게 든 허용해야하는 두 번째 템플릿 매개 변수를 취합니다. 이는 shared_ptr 과 다르다. shared_ptr 은 타입 지우개를 사용하여 커스텀 deleter를 타입의 일부로 저장 하지 않고 저장한다 .





perfect-forwarding