2009-11-27 24 views
17
  1. <? extends T>,<? super T>はC++に相当しますか?C++に<? extends T>,<? super T>の相当語はありますか?

  2. また、TがJavaのインターフェイスでも、<? extends T>,<? super T>が機能しますか?

+0

をあなたがこれを必要ですか?このJava機能をエミュレートしようとするよりも単純で、よりC++のようなソリューションがあるかもしれません。 – jalf

答えて

2

答え:Restrict Template Function

JesperEは、第二の部分のための答えの権利を有します。

+0

引数として渡されたクラスに必要なメソッドが定義されている場合、fool-proofチェックが行われるというルールに従います。 承認されたクラスには、すべての必要な機能があります。しかし、その逆は必ずしも真実ではない。 <のようなものがあれば? extends T>なら、クラス階層を明示的に指定しているので馬鹿です。 – user855

+0

@ajay:型パラメータを基底クラスに制限する場合は、基本クラスインタフェースを正確に使用するため、テンプレート?参照によって基本クラスを操作できますか?これはあなたが探しているタイプの安全性を得るでしょう。テンプレートを使用すると、同じ階層に属していなくても動作する操作を定義できます。それが彼らの力です。あなたの状況でこれが実現できない場合は、あなたがしようとしていることと、それを達成するのに役立つC++機能の詳細についての質問を更新することができます。 –

+0

? extendsは、basetypeの任意のサブクラスを意味します。 – TofuBeer

5

2番目の質問に答える:はい。ジェネリックに関する限り、インターフェースは実際のクラスと同じように扱われます。

最初の質問は、より多くのC++に精通した人に任せます。最初の部分に

12

Javaのようにかなり良い構文糖はありませんが、boost/type_traitsでうまく管理できます。 詳細については、http://www.boost.org/doc/libs/1_40_0/libs/type_traits/doc/html/index.htmlを参照してください。

#include <boost/type_traits.hpp> 
#include <boost/static_assert.hpp> 

class Base {}; 
class Derived_from_Base : public Base {}; 
class Not_derived_from_Base {}; 

template<typename BASE, typename DERIVED> 
void workOnBase() 
{ 
    BOOST_STATIC_ASSERT((boost::is_base_of<BASE, DERIVED>::value)); 
} 

int main() 
{ 
    workOnBase<Base, Derived_from_Base>();  // OK 
    workOnBase<Base, Not_derived_from_Base>(); // FAIL 
    return 0; 
} 

1> D:... \ main.cppに(11):エラーC2027:未定義のタイプを使用する 'ブースト:: STATIC_ASSERTION_FAILURE' 1>と 1> [ 1> X = falseを 1>]

3

C++でテンプレートパラメータの範囲を制限するには、さまざまな特性メカニズムを使用します。その中には、ブーストで使用できる実装があります。

通常、JavaとC#で構文が存在するのは、テンプレートではなくジェネリックを使用しているからです。

Javaジェネリックスは、テンプレート引数として使用される各タイプのコードを生成するのではなく、基本型からの仮想ディスパッチを使用する共有コードを生成します。したがって、通常は、テンプレートパラメータとして使用される型のオブジェクトのメソッドを呼び出すために、この制限を使用しています。

C++では、テンプレートパラメータとして使用される各型のコードが生成されるため、基本型について知る必要はありません。

たとえば、マトリックスのテンプレートクラスでは、ターゲットタイプで+、 - 、*演算子が使用されます。 Inは、これらの演算子をサポートするすべての型に対して使用できます。任意にdoublesとintsに制限されていた場合は、complex<double>のテンプレートを使用することはできません。また、区間演算をサポートする型のテストを実行することもできません。それらを使用します。

同じ形状を持つ任意の型に対して作業する能力は、テンプレートの力であり、より便利になります。そのタイプを(コンパイルされている限り)使用することが有効かどうかを判断するのはクライアントコードに任されており、顧客は常に正しいです。同じ形をした任意の型に対して作業できないこと、およびjava.lang.Object以外のメソッドを呼び出すための制限を指定する必要性は、ジェネリックの弱点です。

2

extensionこれは、「準備ができていませんでした」という悲しいことに、C++ 0xのドラフト標準から削除されました。しかし、静的なアサート(これはC++ 0xとBoostの一部です)を使ってこれをシミュレートすることは可能です。

1

これが私の仕事:

#include <iostream> 

class MyBase {}; 
class A : public MyBase {};  
class B {}; 

template <class T> 
typename std::enable_if<!std::is_base_of<MyBase, T>::value>::type 
Foo(T &v) { 
    std::cout << "Foo 1" << std::endl; 
} 

template <class T> 
typename std::enable_if<std::is_base_of<MyBase, T>::value>::type 
Foo(T &v) { 
    std::cout << "Foo 2" << std::endl; 
} 

int main() { 
    A a; 
    B b; 
    Foo(a); 
    Foo(b); 
    return 0; 
} 
+0

質問は 'is_base_of'よりも前に(そしてそれについては' enable_if')、今日はこれがデフォルトの解決策でなければなりません – Ap31

関連する問題