1

일부 배경 : auto_ptr과 같은 파괴적인 복사 의미 체계를 가질 수있는 정책 기반 스마트 포인터 (예 : Loki 라이브러리의 SmartPtr)를 작성하고 있습니다. 따라서 복사되는 객체를 수정하기 위해 비 const 참조를 사용하는 템플릿 복사 생성자가 필요합니다.복사 생성자 내의 "템플릿 typedef"가 작동하지 않습니다.

내가하려는 것은 파괴적인 복사 의미론이 바람직하지 않을 때 const로 만들기 위해 정책에서 일부 변수에 의해 복사 생성자가 취한 인수의 constness를 매개 변수화하는 것입니다. 컴파일러가 템플릿 인수를 추론 할 수 없기 때문에 여기에 나와있는 아이디어의 단순화 된 코드가 있지만, 불행히도 작동하지 않습니다. 원하는 동작을 달성하는 데 사용할 수있는 다른 기술이 있습니까?

template <typename T, bool isEnabled> struct AddConst { 
    typedef T Type; 
}; 

template <typename T> struct AddConst<T, true> { 
    typedef const T Type; 
}; 

struct MyCopyPolicy { 
    static const bool kIsCopyArgConst = true; 
}; 

template <typename T, class CopyPolicy> struct Foo { 

    // A helper struct to achieve "template typedef". 
    template <typename T2> struct CopyArg { 
     typedef typename AddConst<Foo<T2, CopyPolicy>, 
      CopyPolicy::kIsCopyArgConst>::Type Type; 
    }; 

    Foo() {} 
    // Template copy constructor. Doesn't work. 
    template <typename T2> Foo(typename CopyArg<T2>::Type& rhs) {} 
}; 

int main() { 
    Foo<int, MyCopyPolicy> foo1; 
    Foo<double, MyCopyPolicy> foo2 = foo1; // error! 
} 
+0

<추론하지 않은 컨텍스트 "와 관련하여 와 비슷한 문제가 있습니다. . catch는 ** 모든 ** 가능한 유형에 대해 CopyArg를 인스턴스화하지 않고 컴파일러가 T2를 판별 할 수없고 중첩 된 유형을 비교할 수 없다는 점입니다. –

답변

3

아마도 이와 비슷한 것이 좋습니다. C++ 0x에서 std :: enable_if를 사용했습니다. 부스트를 쉽게 사용하거나 자신 만의 롤을 만들 수 있습니다 (단 몇 줄의 코드).

#include <type_traits> 

struct MyCopyPolicy { 
    static const bool kIsCopyArgConst = true; 
}; 

template <typename T, class CopyPolicy> struct Foo { 

    // A helper struct to achieve "template typedef". 
    template <typename T2> struct CopyArg { 
     typedef CopyPolicy Type; 
    }; 

    Foo() {} 

    template <typename T2> 
     Foo(const T2& rhs, 
       typename std::enable_if<CopyArg<T2>::Type::kIsCopyArgConst>::type* = 0) 
      {} 
    template <typename T2> 
     Foo(T2& rhs, 
       typename std::enable_if<!CopyArg<T2>::Type::kIsCopyArgConst>::type* = 0) 
      {} 
}; 

int main() { 
    Foo<int, MyCopyPolicy> foo1; 
    Foo<double, MyCopyPolicy> foo2 = foo1; // ok! 
} 

나는 이것이 최적이 아니라고 확신합니다. 이것은 단지 당신이 향하고 있던 곳으로부터의 최소 거리라는 목표 중 하나를 가진 엉덩이에서 발을 내디뎠다. 아마 이것은 당신이 가고 싶은 곳이거나, 아마도 당신을 올바른 방향으로 시작하게 할 것입니다.

+0

큰 힌트를 가져 주셔서 감사합니다! 이 트릭은 스택에 생성 된 추가 더미 변수 때문에 조금 더러워 보일지라도. 그러나 나는 그것을 피할 수있는 어떤 가능성도 보이지 않는다. – lizarisk

+0

C++ 0x에서는 기본 함수 인수 대신 기본 템플릿 인수로 "제한 사항"을 추가 할 수 있습니다. 나는 stylistically 기본 서식 파일 인수를 선호합니다. 하지만 제 컴파일러는 그것이 C++ 0x 기능이라고 경고했습니다. –