2017-01-19 224 views
2

我的函數模板有以下問題。如果我有這樣的功能模板,其中T可以任ClassAClassB如何將模板類型作爲參數傳遞給非模板函數?

template<typename T, bool flag> 
void function(T& someT){ 
    if(flag){ /*If 'flag' is true, 'someT' MUST be of type ClassA*/ 
     nonTemplateFunction1(someT); 
    } 
    else{ /*Else 'someT' must be of type ClassB*/ 
     nonTemplateFunction2(someT); 
    } 
} 

而在其他一些文件我有

void nonTemplateFunction1(ClassA& a){...} 

,並在另一個文件中我有

void nonTemplateFunction2(ClassB& b){...} 

現在,如果我打電話給我的函數模板,編譯時出現錯誤:

error: no matching member function for call to 'nonTemplateFunction2'

我想這是因爲編譯器測試了nonTemplateFunction2ClassA作爲參數的例子。但這絕不會發生(至少我,程序員,照顧這個)。我怎樣才能讓我的程序編譯?有什麼解決方法?

編輯:一個更精確的錯誤:

./tabledata.hh:371:9: error: no matching member function for call to 'bulk_insert' bi.bulk_insert(bl, aRel_Vec[j]);

../pax/bulk_insert_pax.hh:21:8: note: candidate function not viable: no known conversion from 'value_type' (aka 'NSM_Relation') to 'PAX_Relation &' for 2nd argument void bulk_insert(const BulkLoader& aBulkLoader, PAX_Relation& aRelation);

回答

1

你混合編譯運行時的決策時間的決定。編譯器確實知道someT的類型,是的,但它不會刪除if分支。基本上處理後,它看起來像這樣:

void function(ClassA& someT){ 
    if(true){ 
     nonTemplateFunction1(someT); 
    } 
    // branch will be optimized away, but still 
    // exists 
    else{ 
     // so this is still erroneous code, even though it never runs 
     nonTemplateFunction2(someT); 
    } 
} 

因此,要麼看到的方式preprocesing中刪除不需要的分支,或使用替代的參考指針或重構你的功能。我不確定選項是什麼,我不擅長模板,但也許你可以通過一些標誌#ifdef

+0

嗯,看來我必須通過然後指向我的T。不是我最喜歡的解決方案,但它應該工作 –

+0

@ N.Weber我認爲這是最快的選擇,是的。 –

0

在C++ 17,你就可以使用if constexpr做到這一點(您的例子代碼按):

class ClassA{}; 
class ClassB{}; 

void nonTemplateFunction1(ClassA&){} 
void nonTemplateFunction2(ClassB&){} 

template<typename T, bool flag> 
void function(T& someT){ 
    if constexpr (flag){ 
     nonTemplateFunction1(someT); 
    } 
    else{ 
     nonTemplateFunction2(someT); 
    } 
} 

int main() { 
    ClassA a; 
    function<ClassA, true>(a); 
} 

看到它的wandbox


在C++ 11/14中,你可以依靠sfinae。它遵循最小,工作示例:

#include<type_traits> 

class ClassA{}; 
class ClassB{}; 

void nonTemplateFunction1(ClassA&){} 
void nonTemplateFunction2(ClassB&){} 

template<typename T> 
std::enable_if_t<std::is_same<T, ClassA>::value> 
function(T& someT){ 
    nonTemplateFunction1(someT); 
} 

template<typename T> 
std::enable_if_t<std::is_same<T, ClassB>::value> 
function(T& someT){ 
    nonTemplateFunction2(someT); 
} 

int main() { 
    ClassA a; 
    function(a); 
} 

如果你喜歡和不希望是明確有關的類型,您也可以使用這個:

template<typename T> 
auto function(T& someT) 
-> decltype(nonTemplateFunction1(someT), void()) { 
    nonTemplateFunction1(someT); 
} 

template<typename T> 
auto function(T& someT) 
-> decltype(nonTemplateFunction2(someT), void()) { 
    nonTemplateFunction2(someT); 
} 
相關問題