2017-01-19 20 views
2

私は私の関数テンプレートに次の問題があります。私はこのような関数テンプレートを使用している場合は、どこTはどちらかClassAまたはClassBのものとすることができる。非テンプレート関数にパラメータとしてテンプレート型を渡すには?

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'

コンパイラがnonTemplateFunction2の呼び出しをパラメータとしてテストするのは、たとえば、ClassAと考えられます。しかし、これは決して起こり得ません(少なくとも私は、プログラマ、これを世話します)。私のプログラムをコンパイルするにはどうすればいいですか?可能な解決策は何ですか?

EDIT:より正確なエラー:

./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にいくつかのフラグを渡すことができますか? C++ 17では

+0

フム、私は合格しなければならないように見えます私のTへのポインタ。私のお気に入りのソリューションではありませんが、それは動作するはずです –

+0

@ N.Weber私はそれが最速のオプションだと思う、はい。 –

0

あなたは(あるとして、あなたの例のコード)それを行うには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でそれを参照してください。


では、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); 
} 
関連する問題