2017-04-22 59 views
2

限制函數模板只接受模板參數的幾個允許值是否被認爲是不好的風格?在C++中限制允許的模板參數是否被認爲是不好的風格?

實施例:

template<typename T> 
class Foo { 

typename std::enable_if<std::is_same<Bar, T>::value, void>::type 
    callFuncInBar() { 
     BarGetValue(); 
    } 


typename std::enable_if<std::is_same<FooBar, T>::value, void>::type 
    callFuncInFooBar() { 
     FooBarGetValue(); 
    } 

}; 

編輯: 我的情況下是這樣的: 我有兩個簡單結構A和B幾乎是相似的:

struct A: public ICompress { 
    void compress() override { 
     next->compress(); 
    } 

    ICompress *next; 
}; 

struct B: public IDecompress { 
    void decompress() override { 
     next->decompress() 
    } 

    IDecompress *next; 
}; 

我的目的是要建立一個模板,它應作爲Compressor或Decompressor實例化:

template<typename T> 
struct codecomp: public T { 
    typename std::enable_if<std::is_base_of<ICompress, T>::value, void>::type 
    compress() { 
     next->compress(); 
    } 

typename std::enable_if<std::is_base_of<IDecompress , T>::value, void>::type 
    decompress() { 
     next->decompress(); 
    } 

    T *next; 
}; 
+1

C++ 17將有[概念](https://en.wikipedia.org/wiki/Concepts_(C% 2B%2B))。在此之前,選擇實例化的唯一可能性是SFINAE(如你的問題)。 –

+2

@HenriMenke不,C++ 17不會有概念。 – cpplearner

+0

簡答:沒有。如果你有一個對某些類型有意義的模板,但對其他類型沒有意義,那麼防止它被其他類型實例化是有意義的。例如,如果模板化的功能僅對數字類型有意義,請阻止其爲非數字類型實例化。你如何執行這個限制可能會或可能不是壞風格。例如,如果您決定在編譯時檢查某個類型是否爲「數字」。 – Peter

回答

2

正如所寫,如果Foo曾經實例化過,代碼將無法編譯。對於不同於Bar的任何類型TFoo<T>的實例化將導致返回類型Foo<T>::callFuncInBar的實例化,這將失敗。同樣,如果TFooBar不相同,則返回類型callFuncInFooBar的實例化將失敗。

我認爲這不是你想要的。

我假設你真正想要的是Foo<T>::callFuncInBar僅在TBar時纔可以調用。這通常由模板專門化處理:專門爲爲T = BarT = FooBar的類模板,並且在主模板中根本不聲明callFuncInBarcallFuncInFooBar成員函數,因此它們將不可用。這完全避免了你的風格問題。 Foo將可用任何模板參數實例化,但具有取決於特定參數的功能集。 (並且被認爲是完美的風格明智的;即使標準庫也這樣做。)

相關問題