2013-07-16 119 views
3

我在Ubuntu 13.04 64位上使用DMD64 D Compiler 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 

我要做接下來就是刪除這兩個writeln行從代碼,並且當我重新編譯代碼,它開始示出作爲以下的錯誤消息:

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不是(也不能)是pure,因爲它是I/O。所以,雖然writeln是在構造函數,它們被推斷爲不pure,但一切的構造做的是pure,所以無需調用writeln,他們成爲pure

在某些情況下,編譯器能夠改變的pure函數的返回類型隱式轉換到immutableshared。這是有效的,因爲在這些情況下,編譯器知道返回的內容是一個新的唯一對象,並且將其轉換爲immutableshared不會違反類型系統。並非所有pure功能出線,作爲參數類型可以影響編譯器是否能保證返回值是唯一的,但很多pure功能都能夠利用這一優勢,並暗示其返回值轉換爲immutableshared。這很有用,因爲它可以避免代碼重複(針對不同的返回類型)或複製 - 因爲如果返回的類型與immutablesharedshared所需的返回類型不匹配,並且您不能保證其他地方不會引用它,你必須複製它以獲得你想要的類型。在這種情況下,編譯器能夠使該對象未提及其他地方的保障,因此它可以安全地投給你。

構造有效返回新的價值觀,這樣他們就可以通過此功能會受到影響。這使得如果構造函數是pure,通常可以從中構造immutableshared值,而不必複製構造函數(就像不是pure時必須執行的操作)。與其他pure功能,這是否工作取決於構造函數的參數類型,但它經常可能,又有利於避免重複代碼。

什麼導致你的問題是,當FixedList的構造函數都是pure時,編譯器能夠使用它們中的任何一個構造shared對象。所以,它不知道選擇哪一個,並給你一個模糊性錯誤。

我已經報道過這個爲bug,理論上編譯器應該更喜歡顯式標記爲shared的構造函數,但編譯器開發人員會決定什麼,我不知道。從pure函數隱式轉換返回值的能力是一個相當新的特性,正是當我們可以或不可以做這些隱式轉換時仍然在探索中,這可能會導致無法預料的問題(像這個可能),以及編譯器錯誤(例如,至少有一個immutable的情況,它當前不應該進行轉換)。我相信,儘管這些問題會很快得到解決。

2

pure一個構造函數可以建立一個對象shared沒有被標記shared本身。

顯然,純度是推定爲構造函數。

writelnpure。所以,在這個地方,施工人員不是pure

writeln被刪除,構造變得pure。兩個構造函數現在都匹配shared調用。

+0

u能提什麼是錯的代碼..? – NREZ

+0

嗯。我想當e嘗試創建一個共享對象,特別是共享構造函數被選中。我在文檔中閱讀了「純函數」,但沒有發現任何關於它的內容。 – tcak

+1

@ user2587136純度不推斷構造。據推斷爲模板的功能,整個類是模板化,所以構造函數模板。 –

相關問題