C ++ 11에서 auto_ptr 지원 중단에 대한 디자인 변경을 처리하는 방법은 무엇입니까?

C ++ 11 (즉, -std=c++11)에서 라이브러리를 테스트하고 있습니다. 라이브러리는 auto_ptr 및 다음 패턴을 사용합니다.

Foo* GetFoo() { autoptr<Foo> ptr(new Foo); // Initialize Foo ptr->Initialize(...); // Now configure remaining attributes ptr->SomeSetting(...); return ptr.release(); } 

C ++ 11 지원 중단 auto_ptr, 그래서 우리는 그것에서 벗어나고 싶습니다.

그러나 코드는 C ++ 03과 C ++ 11을 모두 지원하므로 홱 잡아 당기는 것처럼 간단하지 않습니다. auto_ptr. 라이브러리에 외부 종속성이 없다는 점도 언급 할 가치가 있습니다. C ++ 03을 사용하고 Autotools, Cmake, Boost, …를 사용하지 않습니다.

이동을 위해 디자인 변경을 어떻게 처리해야합니까? C ++ 03과의 호환성을 유지하면서 C ++ 11 용 auto_ptr에서?

댓글

  • auto_ptr 범위가 지정되어 있습니까 (예 : std::auto_ptr), 스마트 포인터가 다른 네임 스페이스 여야합니까 아니면 가져올 수 있습니까?
  • 제외로 Foo::InitializeFoo::Foo로 접을 수 있습니다.
  • @ MSalters-네, 항상 제가 약간 불편한 것 중 하나였습니다. 라이브러리는 1990 년대에 디자인되었고 MFC와 비슷한 디자인이 생각 합니다. 즉, 레벨 C ++ 생성, 그리고 " 상위 레벨 " 객체 생성.이 기능은 트레이드 오프로 사용되었다고 생각합니다. div id = “3e89994714″>

6 개 또는 12 개의 다른 생성자가 없습니다. (이 시점에서 내가 한 일은 POD 유형의 멤버 변수가 C ++ 생성자에서 정상적인 기본값으로 초기화되었는지 확인했습니다.)

Answer

대부분의 측면에서 std::unique_ptr 가 드롭되도록 만들어졌습니다. (하지만 더 안전한) std::auto_ptr 를 대체하므로 코드 변경이 필요한 경우 외에는 거의 필요하지 않습니다. (요청하신대로) unique_ptr 또는 auto_ptr를 사용하도록 코드에 지시합니다.

몇 가지 방법이 있습니다. 이것 (그리고 각각은 자체 목록 장단점이 있습니다). 제공된 코드 샘플이 주어지면 처음 두 옵션 중 하나를 선호합니다 .

옵션 1

#if __cplusplus >= 201103L template <typename T> using auto_ptr = std::unique_ptr<T>; #else using std::auto_ptr; #endif 

Tradeoffs;

  • 전역 네임 스페이스에 auto_ptr 이름을 도입합니다. ; 자신의 " 비공개 " 네임 스페이스
  • 를 정의하여이를 완화 할 수 있습니다.

  • C ++ 17로 마이그레이션 한 후 (auto_ptr는 완전히 제거 될 것입니다.) 더 쉽게 검색하고 바꿀 수 있습니다.

옵션 2

template <typename T> struct my_ptr { #if __cplusplus >= 201103L typedef std::unique_ptr<T> ptr; #else typedef std::auto_ptr<T> ptr; #endif }; 

트레이드 오프;

  • 아마도 작업하기가 더 번거 롭습니다. 현재의 모든 auto_ptr 코드를 다음과 같이 변경해야합니다. my_ptr<T>::ptr
  • 와 같은 것

  • 이름이 글로벌 네임 스페이스에 도입되지 않는 더 나은 안전성

옵션 3

다소 논란의 여지가 있지만 std 클래스를 기본으로 사용하는 것에 대한주의 사항을 참을 준비가되어 있다면

#if __cplusplus >= 201103L template <typename T> using my_ptr = std::unique_ptr<T>; #else template <typename T> class my_ptr : public std::auto_ptr<T> { // implement the constructors for easier use // in particular explicit my_ptr( X* p = 0 ) : std::auto_ptr(p) {} }; #endif 

Tradeoffs;

  • 가상 기반 (특히 비가 상 소멸자)이 예상되는 상속 된 클래스를 사용하려고하지 마십시오. 케이스에 문제가 있지만주의해야합니다.
  • 다시, 코드 변경
  • 잠재적 인 네임 스페이스 불일치-모두 포인터 클래스를 사용하여 시작하는 방법에 따라 다릅니다.

옵션 4

포인터를 새 클래스로 래핑하고 필요한 함수를 멤버에 집계

template <typename T> class my_ptr { // could even use auto_ptr name? #if __cplusplus >= 201103L std::unique_ptr<T> ptr_; #else std::auto_ptr<T> ptr_; #endif // implement functions required... T* release() { return ptr_.release(); } }; 

Tradeoffs;

  • A 실제로 원하는 것은 구현을 " " 교체

댓글

).

  • @jww. OS X (XCode 6.4 및 Apple LLVM 버전 6.1.0 (clang-602.0.53) (LLVM 3.6.0svn 기반))에서 ' m이며 C에 문제가 없습니다. tr1 네임 스페이스 이외의 ++ 03 / 11 믹스가 더 이상 존재하지 않습니다 (libstdc ++가 아닌 libc ++를 사용합니다).tr1이 비 규범 적이라는 것을 알고 있지만 ' 초안 (여기) 에서 파일은 <tr1/...>이어야합니다. 실제로 <memory> 헤더에있는 것만 언급합니다. 12c784e8c1 “>
  • 네임 스페이스.

  • @jww. 컴파일러, 라이브러리 및 대상 장치의 특정 조합이 주어지면 몇 가지 손 스탠드를 더해야 할 수도 있습니다. 그렇지 않으면 OS X에서 clang 및 libc ++로 이동하는 것이 좋습니다. 솔직히 저는 libc ++를 OS X의 새로운 " 네이티브 " C ++ 라이브러리라고 생각합니다. 기본적으로이 라이브러리를 사용합니다. 나는 clang / Apple 관계의 역사와 OS X의 GCC 도구가 오래되었거나 (라이브러리) 제거 된 것 외에는 이러한 주장을 뒷받침 할 방법이 없습니다 (내가 아는 한 GCC가 clang에 대한 얇은 스텁임을 아는 한) ).
  • " 그렇지 않으면 OS X에서 clang 및 libc ++로 이동하는 것이 좋습니다 … " -네, 동의합니다. 그러나 우리는 사용자가 그 선택을하게하고 강제하지 않기를 원합니다. (CXX=...를 지정하거나 부족할 때 암시 적으로 선택합니다.)
  • 여기 ' 사례가 있습니다. 이로 인해 OS X 10.7 및 10.8에서 많은 문제가 발생합니다 : c++ -v -std=c++11 -x c++ - < /dev/null. 덤프 된 포함 디렉토리를 grep'd, 포함하지 않습니다 unique_ptr.
  • 답변

    옵션 5 : 직접 별칭.

    #if __cplusplus >= 201103L template<typename T> using MyPtr = std::unique_ptr<T>; #else #define MyPtr std::auto_ptr #endif 

    장단점 :

    1. 최신 언어 버전 인 AKA C ++ 11 이상의 경우 별칭 유형이 올바른 스마트 포인터에 매핑됩니다. 실제로 std :: auto_ptr에 특정한 API에 의존하는 모든 사용자 코드는 컴파일러에 의해 플래그가 지정되며, 이는 이것이 실제로 수정 될 것이라는 궁극적 인 보장입니다.

    2. 레거시에서 C ++ 03 모드 유형 별칭은 매크로입니다. 이것은 총체적이지만 결과 구문 MyPtr<T>는 나머지 코드 전체에서 C ++ 11 케이스와 동일합니다.

    3. 이를 설정하려면 모든 auto_ptr 변수를 찾아 MyPtr로 변경해야합니다.

    댓글

    • ' 이것이 무엇을 참조하고 있는지 매우 불분명합니다 (그리고 ' 전혀 질문이 아닙니다).
    • @autophage 답변이라고 생각합니다 … 그래서 아마도 질문이 아닐 것입니다.

    답글 남기기

    이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다