2017-01-19 186 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); 
} 
相关问题