2012-12-12 75 views
0

好吧,這是我第一次進入模板,這可能是幾個非常愚蠢,簡單的問題中的第一個。強制編譯錯誤的未專門化模板實例化

考慮:

template <class T> 
void sendit(char *buffer, unsigned len) 
{ 
    // force compile error 
} 

void sendit<first_valid>(char *buffer, unsigned len) 
{ 
    // this is OK 
} 


void sendit<second_valid>(char *buffer, unsigned len) 
{ 
    // this is OK 
} 

基本上,這個想法是,我有一組可以依法由sendit()方法來操作的「東西」,我會專門爲這些東西的模板。如果用戶試圖調用sendit(),(在技術上,sendit()),我想在他的臉上拋出一個編譯錯誤。

這是可行的嗎?如果是這樣,怎麼樣?

這是一個合理的方法嗎?

+0

這只是autodidactic ?因爲除非你只是想學習模板可以做什麼,否則我沒有理由爲此使用模板。 – Beta

+0

這只是我想要做的一部分。我有一套十幾件物品和四套手續。一個可以應用於所有這些,另外三個適用於固定子集。我還計劃在專業領域隱藏其他數據。最終目標是使我的合理設置儘可能簡單和防白癡。 –

+0

可能重複的[如何防止非專業模板實例?](http://stackoverflow.com/questions/7064039/how-to-prevent-non-specialized-template-instantiation) – mako

回答

3

離開它未定義:

template <class T> 
void sendit(char *buffer, unsigned len); 

// C++11 
template <class T> 
void sendit(char *buffer, unsigned len) = delete; 

使用= delete是IMO的首選方法。

或者說,(在C++ 03使用boost)的一些類型的靜態斷言:

template <class T> 
void sendit(char *buffer, unsigned len) { 
    static_assert(sizeof(T) == 0, "must specialize"); // must use sizeof to make it dependant on T 
} 

不管怎樣,你確定你真的需要此模板?我不是說你不應該,只是知道有涉及重載替代品,如:

// This is only if you're using the types as tags 
// Don't do this otherwise!!! 

void sendit(first_valid, char *buffer, unsigned len) 
{ 
    // this is OK 
} 


void sendit(second_valid, char *buffer, unsigned len) 
{ 
    // this is OK 
} 

sendit(first_valid(), ...); // call first 
sendit(second_valid(), ...); // call second 

或者用枚舉,而不是一個類型作爲模板參數:

enum foo { first, second } 

template <foo Foo> 
void sendit(char *buffer, unsigned len); 

void sendit<first>(char *buffer, unsigned len) 
{ 
    // this is OK 
} 
+0

我有幾乎相同的東西記住(雖然嚴格來說這是一個*鏈接*錯誤,而不是*編譯*錯誤)。 – Beta

+0

還有其他的事情正在進行。模板參數將成爲結構中字段的名稱。這些過程將使用字段名來獲取結構中的偏移量和字段的大小,並使用它來控制寫入操作。 (包括長度字段在我的部分是一個錯誤:起訴我。)我想要做的是阻止必須使用它的應用程序員通常做出愚蠢的錯誤,例如試圖將47字節寫入某些可以只有23(有一個涉及硬件處理器間連接。) –

+0

@ JohnR.Strohm可能有更好的方法來做到這一點,但我對你想要的有點困惑。你能否更新你的問題,展示你想要阻止的案例? – Pubby