2014-07-26 7 views
0

unique_ptr을 특수 소멸자로 다시 정의하고 싶습니다. 따라서 다음 코드를 사용하여 unique_ptr의 일부 생성자를 모방하려고합니다. 불행히도 constexpr 생성자가 빌드를 거부하고 이유를 모르겠습니다.constexpr 생성자에서 constexpr 생성자를 사용할 수 없습니다.

class job_ptr : public unique_ptr<Job> 
{ 
public: 
    constexpr job_ptr() 
     : unique_ptr<Job>(), sequencer(nullptr) {} 
    constexpr job_ptr(nullptr_t) 
     : unique_ptr<Job>(nullptr), sequencer(nullptr) {} 
private: 
    FIFOSequencer* sequencer; 
}; 

초기화 목록에서 두 생성자 그러나 clang++는 고려, constexpr을 선언 constexpr constructor never produces a constant expressionnon-literal type 'unique_ptr<Job>' cannot be used in a constant expression 때문이다. 그것은 무엇을 의미하려고합니까? constexpr 생성자 내에서 constexpr 생성자를 사용할 수 없습니까?

도움 주셔서 감사합니다.

+6

당신은 문자 그대로의 형식이 필요합니다 그리고'표준 :: unique_ptr'은 커스텀 Deleter를 제공 할 수있게 해줍니다. (특히 공개적으로 그리고 그 목적을 위해서) – chris

+0

STL을 상속받은 @chris와 완전히 동의합니다. 사소한 상황과'unique_ptr'은 IMHO가 아닙니다. – 101010

+0

리터럴 유형에는 간단한 소멸자가 필요합니다. 일반적으로'unique_ptr'은 리터럴 타입이 될 수 없습니다. – dyp

답변

5

Constexpr 생성자는 가능하지만 the requirement are quite strict입니다. @dyp에서 알 수 있듯이, 가장 큰 문제는 std::unique_ptr이 사소한 소멸자가 아니므로 LiteralType이 아닙니다. 당신이 g 아래 int ++로하려고하면

:

class int_ptr : public std::unique_ptr<int> 
{ 
public: 
    constexpr int_ptr() 
     : std::unique_ptr<int>(), sequencer(nullptr) {} 
    constexpr int_ptr(nullptr_t) 
     : std::unique_ptr<int>(nullptr), sequencer(nullptr) {} 
private: 
    int* sequencer; 
}; 

constexpr int_ptr ptr; 

당신은 매우 명시 적 오류 메시지가 : 주석에 제안, 귀하의 경우에는

unique_ptr.cpp:40:20: error: the type ‘const int_ptr’ of constexpr variable ‘ptr’ is not literal 
    constexpr int_ptr ptr; 
        ^
unique_ptr.cpp:27:7: note: ‘int_ptr’ is not literal because: 
class int_ptr : public std::unique_ptr<int> 
    ^
unique_ptr.cpp:27:7: note: ‘int_ptr’ has a non-trivial destructor 

을 사용자 정의 Deleter가를 사용합니다. STL 컨테이너는 상속에 적합하지 않습니다.

다음

사용자 정의 Deleter가의 예 :

#include <memory> 
#include <iostream> 

template <typename T> 
struct Deleter 
{ 
    void operator()(T* t) 
    { 
     std::cout << "Deleter::oerator(): " << t << std::endl; 
     delete t; 
    } 
}; 

struct A 
{ 
    A() 
    { 
     std::cout << "A::A()" << std::endl; 
    } 

    ~A() 
    { 
     std::cout << "A::~A()" << std::endl; 
    } 
}; 

int main(int argc, char const *argv[]) 
{ 
    std::unique_ptr<A, Deleter<A>> ptr(new A); 


    return 0; 
} 

그것은 출력합니다.. 당신이없는

A::A() 
Deleter::oerator(): 0x600010480 
A::~A() 

이 (live run

+0

@dyp 나쁘게 말하면, 나는 'LiteralType'을 말해야했다. – Johan

+0

@ 당신이 옳다면, 수표가 잘못 처리되었습니다. 편집 중. – Johan

+0

고맙습니다. 그러나 제 'FIFOSequencer * 시퀀서'를 보유하고있는 Deleter를 사용해야하지만, 이미 구축 된 Deleter를 허용하는 생성자가있는 것 같습니다. 내가 unique_ptr에 대한 gcc 소스 코드를 확인했는데, 사실은 deleter의 인스턴스가 uniq_ptr에 포함되어 있는지 몰랐습니다. –