3

我已经在 intrnet 上检查了一段时间,并没有找到任何问题的答案。我想知道 C++ 是否支持有界多态和/或 F 有界多态。

例如,在 Java 中,程序员可以这样做(有界多态):

<T extends Car> void startEngine(T c) {/*body method*/}

还有这个(F-Bounded polymorphism):

<T extends Comparable<T>> void compareWith(T c) {/*body method*/}

C++中有什么等价的吗?

谢谢!

4

2 回答 2

8
<T extends Car> void startEngine(T c) {}

在 C++ 中,与上述等价的是:

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

好吧,语法很丑,但你可以用别名使它更好一点:

//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) 
{
}

或者您可以使用static_assert,正如另一个答案所解释的那样。但是std::enable_ifstatic_assert等价。虽然static_assert让您有机会产生良好的错误消息,但可以帮助您解决重载问题,这意味着仅当是 的基础时std::enable_if才会调用上述函数,否则将选择/考虑其他重载(如果有)。使用,这是不可能的:它只是失败并停止——它不会进一步寻找重载。CarTstatic_assert

同样地,

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

这种技术被称为:

希望有帮助。

于 2013-10-30T17:02:12.853 回答
4

在 C++11 中,您可以使用 static_assert 和类型特征来检查模板参数是否是从特定类派生的类。例如:

#include <type_traits>

class Base {};
class Derived : Base {};
class Other {};

template<class T>
void foo(T t)
{
    static_assert(std::is_base_of<Base, T>::value, "T must be a class derived from Base");
}

int main()
{
    foo(Derived()); // ok
    foo(Base()); // ok
    foo(Other()); // error: static assertion failed: T must be a class derived from Base
}
于 2013-10-30T17:03:57.807 回答