写个写代码遇到的问题
struct Ben
{
private:
int age;
string name;
public:
Ben(int age, string name):age(age),name(name){};
int getAge();
};
struct Kitty
{
private:
int age;
string name;
public:
Kitty(int age, string name):age(age),name(name){};
int getAge();
int getAgePlue();
};
非常常规的两个类,但是第二个比第一个多了一个方法。
int Ben::getAge()
{
return age;
}
int Kitty::getAge()
{
return age;
}
int Kitty::getAgePlue()
{
return age + 1;
}
template<typename STUDENT>
int getStudentAge(STUDENT& stu, bool isKitty)
{
if(isKitty)
{
return stu.getAgePlue();
}
else return stu.getAge();
}
int main()
{
auto ben = Ben{22, "Ben"};
auto kitty = Kitty{22, "Kitty"};
auto benAge = getStudentAge(ben, false);
auto kittyAge = getStudentAge(kitty, true);
}
这里写了一个模板方法,根据传入不同的类调用对应类的方法。
这个代码是编译不过的,编译器会提示对 Ben
类找不到 getAgePlue
方法。
templateTest.cpp: In instantiation of 'int getStudentAge(STUDENT&, bool) [with STUDENT = Ben]':
templateTest.cpp:33:48: required from here
templateTest.cpp:23:20: error: 'struct Ben' has no member named 'getAgePlue'; did you mean 'getAge'?
23 | return stu.getAgePlue();
| ~~~~^~~~~~~~~~
| getAge
如果你像我一样最开始不了解模板方法的原理,你可能有很多种方法解决这个问题。比如这里,其实是传了一个 bool
值进去的,就是 isKitty
,在调用的地方也已经特化了。但是不太行。
或者这样?
std::is_same
可以判断两个类型是否一致,也是模板方法中针对某个特殊类型进行特殊处理的常用方法。
if(isKitty and is_same<STUDENT,Kitty>::value)
{
return stu.getAgePlue();
}
我也尝试过在调用的时候,显式声明typename
的类型(显式实例化)。
auto kittyAge = getStudentAge<Kitty>(kitty, true);
但是都没什么用,说实话。
C++其实并没有真正意义上的泛型编程。模板并不创建任何函数,而只是告诉编译器如何定义函数。比如这里,需要对Ben
取age
的函数时,编译器将按模板模式创建这样的函数,显然,Ben
并没有getAgePlue
。
回到这里,最简单的解决方法就是将模板函数降级成普通函数。或者对模板执行特化。也许还有其他好的解决办法,但我目前能想到的就这两种。