C++中的模板:(F-)有界多态

dde*_*mez 2 c++ polymorphism

我已经检查了一段时间的内联网,并找到了我的问题的任何答案.我想知道C++是否支持有界多态性和/或F-有界多态性.

例如,在Java程序员中可以做到这一点(boundedn polymorphism):

<T extends Car> void startEngine(T c) {/*body method*/}
Run Code Online (Sandbox Code Playgroud)

这个(F-有界多态性):

<T extends Comparable<T>> void compareWith(T c) {/*body method*/}
Run Code Online (Sandbox Code Playgroud)

在C++中有什么相同的东西吗?

谢谢!

Naw*_*waz 7

<T extends Car> void startEngine(T c) {}
Run Code Online (Sandbox Code Playgroud)

在C++中,与上面相同的是:

template<typename T, typename Unused= typename std::enable_if<std::is_base_of<Car,T>::value>::type>
void startEngine(T c) {}
Run Code Online (Sandbox Code Playgroud)

好吧,语法很难看,但你可以用别名使它更好一些:

//first define a (reusuable) alias
template<typename D, typename B>
using extends = typename std::enable_if<std::is_base_of<B,D>::value>::type;

//then your code would look like this
template<typename T, typename Unused=extends<T,Car> >
void startEngine(T c) 
{
}
Run Code Online (Sandbox Code Playgroud)

或者你可以使用static_assert,正如另一个答案所解释的那样.但是,std::enable_ifstatic_assert等价的.虽然static_assert为您提供了生成良好错误消息的机会,但std::enable_if可以帮助您解决重载问题,这意味着只有在Car作为基础的情况下才会调用上述函数T,否则将选择/考虑其他重载(如果有).有了static_assert,这是不可能的:它只是失败并停止 - 它看起来不会过载.

同样,

//then your code would look like this
template<typename T, typename Unused=extends<T,Comparable<T>> >
void compareWith(T c) 
{
}
Run Code Online (Sandbox Code Playgroud)

这种技术被称为:

希望有所帮助.

  • @ excalibur1491如果类型不是Car的子类,则实例化模板失败; 在这种情况下,没有"未使用"的类型.如果类型是从Car派生的,那么Unused确实有一个类型,但它并不重要,因为它没有被使用.Unused只是一个伪参数,可以让'if_derived_from'表达式放在那里.'if_derived_from'的作用是说"如果类型是从Car派生的,那么继续并实例化该模板以便可以使用它.否则假装这个模板不存在." 这是基于称为SFINAE的C++技巧. (2认同)