Roy*_*itz 5 c++ inheritance class function stdlist
为什么第二次调用print_all
函数会导致静态语义错误?
#include <list>
using std::list;
class foo {
// ...
};
class bar : public foo {
// ...
};
static void print_all(list<foo*>& L) {
// ...
}
list<foo*> LF;
list<bar*> LB;
// ...
print_all(LF); // works fine
print_all(LB); // static semantic error
Run Code Online (Sandbox Code Playgroud)
该std::list
是一个模板类,这意味着,一个需要用一个类型实例,以获取所需的模板类全类定义。当std::list
使用foo
和实例化时bar
,我们将获得完全不同的类型。这意味着bar
a是 foo
(由于继承),但是a与 std::list<foo*>
类型不同std::list<bar*>
。因此,根据给定的定义,print_all(std::list<foo*> &L)
只能接受指向的指针foo
的列表。
解决该问题的最简单方法是模板化函数。使print_all
templeted一个功能,通过它也可以接受其他类型(即std::list<foo*>
,std::list<bar*>
等...)了。
template<typename Type> // --> template parameter
void print_all(std::list<Type*> const& L) // --> function parameter
// ^^^^^^ --------> use `const-ref` as the list is
// not being modified inside the function
{
// print the list
}
Run Code Online (Sandbox Code Playgroud)
然而,现在将接受其他类型太,如std::list<int*>
,std::list<float*>
等。(其它所有可能的类型)。这可能不是您想要的行为。那里有一种所谓的“替代失败不是错误”(SFINAE)技术,通过这种技术,可以print_all
并且仅当模板Type
std::is_base_of
是foo
类时,才可以限制模板化函数的实例化。就像是
#include <type_traits> // std::enable_if, std::is_base_of
template<typename T>
auto print_all(std::list<T*> const& L)-> std::enable_if_t<std::is_base_of_v<foo, T>> // in C++14
// or
// auto print_all(std::list<T*> const& L)-> typename std::enable_if<std::is_base_of<foo, T>::value>::type // in C++11
{
// print the list
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
86 次 |
最近记录: |