3

私はしばらくの間インターネットをチェックしてきましたが、私の質問に対する答えは見つかりませんでした。C++ が境界ポリモーフィズムや F 境界ポリモーフィズムをサポートしているかどうかを知りたいです。

たとえば、Java プログラマーはこれを行うことができます (boundedn ポリモーフィズム):

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

そしてこれ(F境界ポリモーフィズム):

<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_if、 とstatic_assertは等価ではありません。Whilestatic_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) 
{
}

この手法は次のように知られています。

それが役立つことを願っています。

于 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 に答える