我正在尝试执行以下操作:
template <class T>
void foo(T * ptr){
...a lot of code ...
if(std::is_base_of<Bar<T>,T>::value){
Bar<T> & bar = *ptr;
...a lot of code ...
}
...a lot of code
}
如果我用一个Bar的子类编译这个函数,一切正常,但是如果我尝试使用哪个isnt进行编译,我会在
处收到错误Bar<T> & bar = *ptr;
线。
这是怎么回事,因为当T
不是Bar<T>
的子类时,这条线是否会被执行?
如果这不是通常的方法,我怎样才能以正确的方式实现这一目标?
答案 0 :(得分:1)
因为Bar<T>
不是T
的子类,
Bar<T> & bar = *ptr;
这会导致编译错误。事实上,它被包含在一个if()
语句中,该语句的计算结果为false
,并且代码的这一部分永远不会被执行,并不会改变这一事实。
这里的正确方法是专门化模板。
这些方面的东西:
template <class T, bool is_subclass=std::is_base_of<Bar<T>,T>::value>
void foo(T * ptr);
template <class T>
void foo<T, true>(T * ptr){
...a lot of code ...
Bar<T> & bar = *ptr;
...a lot of code ...
...a lot of code
}
template <class T>
void foo<T, false>(T * ptr){
...a lot of code ...
...a lot of code
}
您现在有两个不同版本的foo
模板,一个用于模板参数是子类的情况,另一个不是。{/ p>
foo()
的两个版本都可能包含大量公共代码。因此,您可能需要在此处做更多的工作,将公共代码分解为他们自己的独立模板函数,您将从foo()
调用它们。
答案 1 :(得分:1)
这可以通过多种方式实现,例如标签调度:
template <class T>
void bar(T* ptr, std::true_type)
{
// ...a lot of code ...
}
template <class T>
void bar(T*, std::false_type)
{
// do nothing
}
template <class T>
void foo(T * ptr){
//...a lot of code ...
bar(ptr, std::is_base_of<Bar<T>,T>{});
//...a lot of code
}