2014-12-28 79 views
0

我想在C++中使用模板實現HashMap(並且同時學習模板如何工作)。爲此,我需要調用參數類型爲T的方法T :: equals()從模板類的方法調用類型參數的方法(C++)

這是簡化的什麼,我需要的代碼:

template < class T > class Map{ 
    public: 
    T* [] cells; 
    replaceIfEquals(int index, T a){ 
     if(cells[index].equals(a); ) cells[index] = a; 
    }; 
}; 

這裏假設T應該像

class Point2D : public Comparable { 
    public: 
    virtual bool equals(Object o){ Point2D p = (Point2D)o;  return (ix == p.ix) && (iy == p.iy); }; 
}; 

其中一些更普遍的類型的子類型(在Java中我會使用的界面)

class Comparable { 
    public: 
    virtual bool equals(Object o){ return false; }; 
}; 

我想我錯過了一些非常基本的c模板的接受。

+0

什麼問題? – 0x499602D2

+0

'T'可以是任何類,並不是所有的類都有一個方法'T.equals(Object o)'。那麼編譯器如何知道我稍後將只使用'Comparable'類? –

+1

編譯器只有在它試圖用特定的T實例化模板時才知道,並檢查該T是否具有適當的成員函數。 –

回答

0

您可以做一個特質is_comparable<T>如果operator==T定義返回true或false,那麼你可以使用static_assert來創建Map類中的編譯時斷言:

template<class T, class = void> 
struct is_comparable 
    : std::false_type { }; 

template<class T> 
struct is_comparable<T, decltype(void(std::declval<T>() == std::declval<T>()))> 
    : std::true_type { }; 

template<class T> 
class Map 
{ 
    // ... 
    static_assert(is_comparable<T>::value, "T must be comparable"); 
}; 

如果傳遞Map一個類型,其operator==沒有定義,你會得到一個與自定義m編譯錯誤essage。就像邁克爾說的那樣,這就是你如何在C++中完成的。

0

在C++中忘記「對象」或繼承「等於」。這是一個Java-ISM。在C++中,我們這樣做是這樣的:

class Point2D { 
    public: 
    // ... 
    bool operator==(const Point2D& other) const; 
    // ... 
}; 

在地圖中的代碼,你可以簡單地使用x == y代替x.equals(y)。請注意,您的地圖當前有一個指針列表,因此您需要取消引用他指向的操作(也就是說,您需要執行*xPtr == *yPtr來比較指向的值而不是地址)。

+0

好吧,但它應該是一樣的 - 編譯器如何知道運算符'=='是爲所有可能的參數'T'定義的? –

+1

@ProkopHapala這就是模板與繼承的不同之處。在使用模板時,編譯器會驗證模板是否使用了提供模板使用的所有函數的類型實例化。因此你根本不需要繼承關係。 –