2013-07-16 2 views
3

Ubuntu 13.04 64 비트에서 DMD64 D 컴파일러 v2.063.2를 사용하고 있습니다. 클래스가이 방식으로 작성되어 있지만, 주요 기능에, 내가 그 코드를 작성 writeln이 없을 때 생성자가 없습니다.

class FixedList(T){ 
    // list 
    private T[] list; 

    // number of items 
    private size_t numberOfItems; 

    // capacity 
    private size_t capacity; 

    // mutex 
    private Mutex listMutex; 

    // get capacity 
    @property public size_t Capacity(){ return capacity; } 
    @property public shared size_t Capacity(){ return capacity; } 

    // constructor 
    public this(size_t capacity){ 
     // initialise 
     numberOfItems = 0; 
     this.capacity = capacity; 

     writeln("Cons Normal"); 
    } 

    // constructor 
    public shared this(size_t capacity){ 
     // initialise 
     numberOfItems = 0; 
     this.capacity = capacity; 

     // create mutex 
     listMutex = cast(shared)(new Mutex()); 

     writeln("Cons Shared"); 
    } 
} 

:이와

auto list1 = new shared FixedList!int(128); 
auto list2 = new FixedList!int(128); 

출력이, 아니이 나는 아래와 같은 클래스를 작성했습니다

모든 출력에서 ​​오류는 다음과 같습니다 :

Cons Shared 
Cons Normal 

내가 다음에 할 것은 모두을 제거하는 것입니다 658,113,210 코드에서 선 및 I 코드를 컴파일 할 때, 아래와 같은 에러 메시지를 나타내는 시작한다 :

src/webapp.d(61): Error: constructor lists.FixedList!(int).FixedList.this called with argument types: 
    ((int) shared) 
matches both: 
    lists.d(28): lists.FixedList!(int).FixedList.this(ulong capacity) 
and: 
    lists.d(37): lists.FixedList!(int).FixedList.this(ulong capacity) 
src/app.d(61): Error: no constructor for FixedList 
src/app.d(62): Error: constructor lists.FixedList!(int).FixedList.this called with argument types: 
    ((int)) 
matches both: 
    lists.d(28): lists.FixedList!(int).FixedList.this(ulong capacity) 
and: 
    lists.d(37): lists.FixedList!(int).FixedList.this(ulong capacity) 
src/app.d(62): Error: no constructor for FixedList 
make: *** [all] Error 1 

기본적 writeln 함수는 에러를 방지한다. 실제로 writeln은 많은 곳에서 예방하고 있으며 왜 이런 일이 일어나고 있는지 확실하지 않습니다.

심지어는 m32 플래그를 사용하여 32 비트 용으로 컴파일하려고 시도했지만 여전히 동일합니다. 내가 잘못했거나 버그입니까?

답변

3

pure, nothrow@safe이 템플릿 기능에 대해 추론된다. FixedList은 템플릿 처리되므로 생성자의 템플릿이 만들어집니다. writeln은 I/O를 수행하지 않으므로 pure이 아니며 사용할 수 없습니다. 따라서 writeln은 생성자에 있지만 pure이 아닌 것으로 추정되지만 생성자가 수행하는 모든 항목은 pure이므로 writeln을 호출하지 않으면 pure이됩니다.

컴파일러에서는 pure 함수의 반환 형식을 immutable 또는 shared으로 암시 적으로 변환하도록 변경할 수 있습니다. 이러한 경우 컴파일러에서는 반환되는 내용이 새롭고 고유 한 객체이며,이 객체를 immutable 또는 shared으로 형 변환하면 형식 시스템을 위반하지 않는다는 것을 알기 때문에 작동합니다. 매개 변수 유형이 컴파일러는 반환 값이 고유하다는 것을 보장 할 수 있습니다, 그러나 많은 pure 기능이 활용하고 암시 적으로 immutable 또는 shared 자신의 반환 값을 변환 할 수 있는지 여부에 영향을 줄 수있는 모든 pure 기능, 자격. 이는 코드 중복 (다른 반환 유형의 경우) 또는 복사를 피할 수 있기 때문에 유용합니다. 반환 된 유형이 immutable 또는 shared과 관련하여 필요한 유형과 일치하지 않아 다른 곳에서 참조되지 않는다고 보장 할 수 없기 때문에 유용합니다. , 당신은 당신이 원하는 타입을 얻기 위해 그것을 복사해야합니다.이 경우 컴파일러는 객체가 다른 곳에서 참조되지 않도록 보장하여 안전하게 캐스팅 할 수 있습니다.

생성자는 새로운 값을 효과적으로 반환하므로이 기능의 영향을받을 수 있습니다. 이렇게하면 생성자가 pure 인 경우 생성자를 복제하지 않고도 immutableshared 값을 구성 할 수 있습니다 (예 : pure이 아닌 경우). 다른 pure 함수와 마찬가지로이 함수가 작동하는지 여부는 생성자의 매개 변수 유형에 따라 다르지만 가능한 경우가 많으며 코드 중복을 방지하는 데 도움이됩니다. 당신에게 문제의 원인은 무엇

FixedList의 생성자 모두 pure을 때, 컴파일러가 shared 객체를 생성하기 위해 그들 중 하나를 사용할 수 있다는 것이다. 그래서, 어느 것을 선택해야할지 모르고, 모호함 오류를줍니다.

컴파일러가 shared으로 명시 적으로 표시된 생성자를 선호해야한다는 이론에 대해 bug으로보고했지만 컴파일러 개발자가 결정할 것입니다. 잘 모르겠습니다. pure 함수의 반환 값을 암시 적으로 변환하는 기능은 상당히 새로운 기능이며 암시 적 변환을 수행 할 수 있고 수행 할 수없는 경우에도 여전히 탐색 중이므로 예기치 않은 문제 (예 : 컴파일러 버그 (예 : immutable에 적어도 하나의 사례가 있습니다. 현재는 그렇지 않아야합니다.) 나는이 문제들이 상당히 빨리 다림질 될 것이라고 확신한다.

2

pure 생성자는 shared이라고 표시되지 않고 shared 개체를 만들 수 있습니다.

분명히 순수가 생성자에 대해 추론됩니다.

writelnpure이 아닙니다. 따라서, 그 자리에, 생성자는 pure이 아닙니다.

writeln을 제거하면 생성자는 pure이됩니다. 두 생성자가 모두 shared 호출과 일치합니다.

+0

코드에 무엇이 잘못되었는지 언급 할 수 있습니까? – NREZ

+0

흠. 전자가 공유 객체를 만들려고 할 때, 특히 공유 생성자가 선택되었을 때 나는 생각했다. 나는 문서에서 '순수한 함수'를 읽었지만 그것에 대해서는 아무 것도 발견하지 못했습니다. – tcak

+1

@ user2587136 생성자에 대한 순도가 유추되지 않습니다. 그것은 템플릿 함수에 대해 추론되며, 전체 클래스는 템플릿 처리되므로 생성자는 템플릿 처리됩니다. –