2009-11-27 74 views
17
  1. 在C++中是否有等效的<? extends T>,<? super T>在C++中是否有等效的<? extends T>,<? super T>?

  2. 另外,是否<? extends T>,<? super T>工作,即使T是Java中的接口?

+0

你需要什麼用的?可能會有更簡單,更類似於C++的解決方案,而不是試圖模擬此Java功能 – jalf 2009-11-27 11:26:50

回答

2

回答第一部分:Restrict Template Function

JesperE有第二部分正確的答案。

+0

遵循如下規則:如果作爲參數傳遞的類具有定義的必要方法,那麼這是一種傻瓜檢查。 經批准的課程將具備所有必要的功能。但相反並不總是如此。如果你有類似<的東西?擴展T>然後它是傻瓜證明,因爲我們明確指定類層次結構 – user855 2009-11-27 07:10:31

+0

@ajay:如果你想限制類型參數作爲基類,因爲你完全使用基類接口,那麼你是否需要使它成爲一個模板?你可以通過引用來操作基類嗎?這會爲您帶來您所需要的類型安全。通過模板,您可以定義不需要來自同一層次結構的類型的操作。這是他們的力量。如果在你的情況下這是不可行的,也許你可以更新有關你想要做什麼以及C++功能可以幫助你實現的更多細節。 – 2009-11-27 07:37:41

+0

?擴展意味着基類型的任何子類。 – TofuBeer 2009-11-27 07:40:36

5

回答你的第二個問題:是的。就泛型而言,接口被視爲與真實類相同。

我會把第一個問題留給更多的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 =假 1>]

3

您可以使用各種特徵機制在C++中限制模板參數的範圍,其中有些實現可用於boost。

通常你不會 - Java和C#中語法存在的原因是它們使用泛型而不使用模板。

Java泛型生成共享代碼,該代碼使用來自基本類型的虛擬分派,而不是爲每個用作模板參數的類型生成代碼。所以通常你使用的限制是爲了允許你調用用作模板參數的類型的對象的方法。

由於C++爲用作模板參數的每種類型生成代碼,因此不需要知道它們的基本類型。

例如,矩陣的模板類將在其目標類型上使用+, - ,*運算符。然後可以用於支持這些操作員的任何類型。如果它被任意限制爲double s和int s,那麼您不能使用帶有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 2017-05-25 18:07:47

相關問題