2011-11-11 60 views
3

我想實現一個模板C++模板瓦特/指針 - 無法將模板參數

template <class object_t, long size, object_t nullObject> 
class lf_deque 
{ 
    // ... 
} 

當我嘗試實例化這個模板,一個int,它編譯罰款,但如果我嘗試用實例指針我得到的錯誤:

could not convert template argument '0' to 'int*' 

lf_deque<int, 10, 0> intDeque; // WORKS 
lf_deque<int*, 10, 0> ptrDeque; // ERROR 

任何想法或想法,爲什麼我會得到這種不一致?

+0

什麼是編譯器?這在MSVC 2010編譯罰款。 – MSN

+0

這是從海灣合作委員會4.5.2 – Jerunh

回答

3

在模板時的功能/類解決了與 ADL(參數依賴查找) 功能模板參數推導,沒有隱式轉換。只有完全匹配的參數才能解析實例化適當的模板函數/類。這是錯誤的根源。

編譯器會告訴你,它不能隱式最後一個參數轉換0int *,因爲當你傳遞的第一個參數爲int *object_tint *而編譯器期望的int *作爲第三個參數爲好。它告訴你0是一個無效的類型作爲類模板的第三個參數。

+0

然而,沒有任何隱式轉換0轉換爲指針。相反,0(或實際上,任何整數類型的值爲零的常量整型表達式)是一種特殊情況(空指針文字)。我相信它應該在這個例子中工作,並懷疑編譯器錯誤。無論如何,解決方法很簡單:只需添加一個明確的演員。 – celtschk

+1

這裏沒有參數相關的查找。依賴於參數的查找用於在與參數類型相關聯的命名空間中查找重載解析候選函數,但是這裏不涉及函數,重載和命名空間。 –

+0

我想你的意思是參數類型推理,但這隻適用於函數,這裏沒有涉及的函數。 –

2

你真的需要傳遞nullObject實例作爲模板的一部分嗎?你可以通過構造函數來完成嗎?

使用G ++

#include <string> 


template <class object_t, long size> 
class lf_deque 
{ 
public: 
    lf_deque(const object_t& nullObject){ 
     //... 
    }; 

protected: 
    lf_deque(){ 
     // ... 
    }; 
}; 

int main(){ 

    lf_deque<int,10> intDeque(0); 
    lf_deque<std::string,10> myStringDeque(""); 

    int myInt = 4; 
    lf_deque<int*,10> intPtrDeque(&myInt); 

    lf_deque<int*,10> intPtrDequeZero(0); 

    return 0; 
} 

如果這是不可行的,也許你可以存儲值作爲一個靜態成員,而不是下面的編譯。

#include <string> 

template <class object_t, long size> 
class lf_deque 
{ 
public: 
    lf_deque(){ 
     //.. 
    } 
    static object_t nullObject; 
}; 
template<class object_t, long size> object_t lf_deque<object_t,size>::nullObject; 

int main(){ 

    lf_deque<int,10>::nullObject = 0; 
    lf_deque<int,10> intDeque; 

    lf_deque<int*,10>::nullObject = 0; 
    lf_deque<int*,10> intPtrDeque; 

    return 0; 
} 
+1

+1,因爲代碼示例很好,但關於ADL的觀點是錯誤的。這裏沒有*參數相關的查找*。 –

+0

第一個例子最終成爲我選擇的解決方案。我不需要將nullObject定義爲模板參數。我在構造函數中傳遞了它。 – Jerunh

+0

感謝@Jan對ADL的評論不正確。我已經編輯了相應的答案。 – Joel

3

下面是標準(ISO/IEC 14882:2011(E))不得不說,在「21年3月14日模板非類型參數[temp.arg.nontype] [#5],頁331 :

Although 0 is a valid template-argument for a non-type template-parameter of integral type, it is not a valid template-argument for a non-type template-parameter of pointer type. However, both (int*)0 and nullptr are valid template-arguments for a non-type template-parameter of type 「pointer to int.」

特別地,參數依賴查找無關,在這種情況下做的,錯誤的原因是,對於一個指針無類型模板參數唯一允許轉換是:資格轉換,陣列到指針轉換 或者,如果模板參數的類型爲std::nullptr_t - 空指針轉換