我的功能模板存在以下问题。如果我有这样的功能模板,其中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){...}
现在,如果我调用我的函数模板,编译时出错:
错误:没有匹配的成员函数来调用&#39; nonTemplateFunction2&#39;
我想这是因为编译器测试nonTemplateFunction2
的调用,例如ClassA
作为参数。但这永远不会发生(至少我,程序员,照顾这个)。我怎样才能让我的程序编译?有哪些可能的解决方案?
编辑:更准确的错误:
./ tabledata.hh:371:9:错误:没有匹配的成员函数来调用&#39; bulk_insert&#39; bi.bulk_insert(bl,aRel_Vec [j]);
../ pax / bulk_insert_pax.hh:21:8:注意:候选功能不可行:没有已知的转换来自&#39; value_type&#39; (又名&#39; NSM_Relation&#39;)到&#39; PAX_Relation&amp;&#39;第二个参数 void bulk_insert(const BulkLoader&amp; aBulkLoader,PAX_Relation&amp; aRelation);
答案 0 :(得分: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);
}
}
因此要么在预处理过程中看到删除不需要的分支的方法,要么使用指针而不是引用或重构您的函数。我不确定选项是什么,我不熟悉模板,但也许你可以将一些标志传递给#ifdef
?
答案 1 :(得分: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);
}