2016-08-24 2 views
2

나는 순수한 통사 적 목적을 위해 특정 방법으로 함수를 호출하기 위해 사용하는 class을 가지고있다. 이는 다음과 같은 단순화 된 예입니다.소멸자를 삭제하면 실천할 수없는 수업이 생깁니 까?

#include<iostream> 

template<class T1> 
struct make{ 
    template<class T2> 
    static T1 from(T2 const& t2){ 
     return T1{}; //or something more complicated 
    } 
}; 

int main(){ 
    double d = make<double>::from(2); 
    std::cout << d << '\n'; 
} 

이제이 클래스를 인스턴스화하면 안됨을 사용자에게 경고하려고한다고 가정합니다. 수업을 견딜 수있는 용도가있을 수 있지만 그게 가능하지 않으면 호기심이 있습니까?

먼저 나는 기본 생성자

template<class T1> 
struct make{ 
    make() = delete; 
    template<class T2> 
    static T1 from(T2 const& t2){ 
     return T1{}; //or something more complicated 
    } 
}; 

을 삭제하려하지만이 여전히 가능 : 마지막으로

make<double> m{}; // valid 

, 내가 소멸자를 삭제 시도하고 그

template<class T1> 
struct make{ 
    ~make() = delete; 
    template<class T2> 
    static T1 from(T2 const& t2){ 
     return T1{}; //or something more complicated 
    } 
}; 
작업 듯

하지만 클래스는 여전히 0으로 할당 될 수 있습니다..

나는 소멸자 및 삭제 생성자, (어떤 사본에 대한 및 생성자를 이동?)

이 인스턴스화를 허용하는 가장 좋은 방법 모두를 삭제해야 하는가? 여기 코드 : http://coliru.stacked-crooked.com/a/0299c377c129fffb

#include<iostream> 

template<class T1> 
struct make{ 
    make() = delete; 
    ~make() = delete; 
    template<class T2> 
    static T1 from(T2 const& t2){ 
     return T1{}; //or something more complicated 
    } 
}; 

int main(){ 
    double d = make<double>::from(2); 
    std::cout << d << '\n'; 
    make<double> m{}; // compile error (no destructor) 
    auto p = new make<double>{}; // compile error (no constructor) 
} 

답변

3

하지만이 여전히 가능은 :

make<double> m{}; // valid 

... 나는 그 일을 할 몰랐다. 하지만 지금은 내가, 나도 알아 그것은 작동합니다. 그리고 그러므로 그것을 멈추는 방법.

귀하가 신고 한대로 make<T>이 (가) 집합체이기 때문에 효과가 있습니다. 삭제 된 기본 생성자가 있어도 C++은 여전히이를 집계로 간주합니다. 그리고 aggregate에 braced-init-lists를 사용하면 aggregate initialization이됩니다.

방법

는 간단하다 중지 : 개인 회원의 힘 make<T>가 더 이상 집계 할 수 없습니다

template<class T1> 
struct make{ 
    template<class T2> 
    static T1 from(T2 const& t2){ 
     return T1{}; //or something more complicated 
    } 

    make() = delete; 

private: 
    char c; //Not an aggregate 
}; 

그건 : 더 이상 집계하지 않습니다. 따라서 집계 초기화에서는 사용할 수 없으므로 {}은 기본 생성자를 호출하려고 시도합니다. 삭제 된 이후 자연스럽게 실패합니다.

여전히 복사 가능한 체조가 make<T>의 인스턴스를 만드는 데 계속 사용될 수 있습니다. 당신은 그것을 virtual 소멸자를 제공하여 사람들을 종료 할 수 있습니다 :

template<class T1> 
struct make{ 
    template<class T2> 
    static T1 from(T2 const& t2){ 
     return T1{}; //or something more complicated 
    } 

    make() = delete; 

private: 
    char c; //Not an aggregate 
    virtual ~make() = default; 
}; 

한다고 해당 유형의 객체를 만드는 것을 법적 C++ 코드를 방지하기에 충분합니다.

+1

좋은 통찰력을 가지고 있지만, 코드는 여전히 허용됩니다 :'auto p = new make ;', 생성자를 삭제 (또는 비공개)해야합니다. – alfC

+0

@alfC : 나는 구조물을 삭제하는 것을 의미했습니다.그것은 단지 복사 및 붙여 넣기 오류 일뿐입니다. –

+0

ok, 일단 생성자와 소멸자가 삭제되거나 비공개로 선언되면 무의미한 상태로 만들면 어떻게 될까요? – alfC

관련 문제