2011-03-09 94 views
3

我有以下的地圖類型...解決運營商歧義

std::map<D3DXCOLOR, ID3DXMesh*> 

在編譯過程中,xfunctional抱怨說,它無法解決有關的密鑰類型歧義;

error C2593: 'operator <' is ambiguous 

編譯器檢測到的候選運算符如下;

  1. 內置C++操作者<(DWORD,DWORD)
  2. 內置C++操作者<(FLOAT,FLOAT)
  3. 內置C++操作者<(D3DCOLORVALUE,D3DCOLORVALUE)

D3DXCOLOR結構由4個浮標組成r,g,ba,但沒有定義運營商<。但它確實爲DWORD FLOAT和D3DCOLORVALUE提供了強制轉換函數,因此是候選列表中的條目。

我正在考慮解決此問題的最佳方法。我可以爲D3DXCOLOR編寫我自己的內聯運算符,將顏色包裝在提供自己的運算符<的新類中,或者可以以某種方式向編譯器提示哪些實現應該從候選列表中選擇? DWORD運算符<將充分滿足我的要求。

回答

3

您有三個選項。假設,例如,你希望他們相比colorvalues:

1)定義operator<

bool operator<(const D3DXCOLOR &lhs, const D3DXCOLOR &rhs) { 
    return static_cast<D3DCOLORVALUE>(lhs) < static_cast<D3DCOLORVALUE>(rhs); 
} 

2)專業std::less

namespace std { 
    template <> 
    struct less<D3DXCOLOR> { 
     bool operator()(const D3DXCOLOR &lhs, const D3DXCOLOR &rhs) { 
      return static_cast<D3DCOLORVALUE>(lhs) < static_cast<D3DCOLORVALUE>(rhs); 
     } 
    }; 
} 

3)提供第三個模板參數您的地圖 - 請注意,這會改變地圖的類型,所以如果您將地圖大量傳遞,可能會很不方便。但它表示排序僅用於此地圖,而不是用於任何其他目的的規範「正確」顏色順序。

struct mycomparator { 
    bool operator()(const D3DXCOLOR &lhs, const D3DXCOLOR &rhs) { 
     return static_cast<D3DCOLORVALUE>(lhs) < static_cast<D3DCOLORVALUE>(rhs); 
    }  
}; 

std::map<D3DXCOLOR, ID3DXMesh*, mycomparator> 
+0

謝謝,這非常合理。由於地圖僅用於內部對象,因此我選擇使用比較函子對象提供地圖,該對象的執行在執行<操作時將lhs和rhs都轉換爲DWORD。 – 2011-03-09 11:46:08

+0

+1。我喜歡第二種解決方案! – Nawaz 2011-03-09 12:23:08

+0

第二個解決方案非常神祕 - 我不確定你是否真的想*專門化'std :: less',但不能重載'operator <'來匹配。這意味着'std :: map'和'std :: set''只對這個類型起作用,但是普通的比較不會,當你定義的順序基本上是任意的有一個。但是這也意味着函數式編程作爲一種副作用起作用,使用基本上任意的順序,如果有充分的理由不提供'operator <',這是危險的。 – 2011-03-09 12:34:43

0

您需要編寫自己的運營商<,或者爲地圖提供比較函數。

struct CompareColor { 
    bool operator()(D3DXCOLOR const & L, D3DXCOLOR const & R) const { 
    // Compare and return whether L is less than R 
    } 
} 

map<D3DXCOLOR, ID3DXMesh*, CompareColor> TheMap; 
2

您可以將一個小於仿函數傳遞給應該使用的map類模板。

struct D3DXCOLOR_less { 
    bool operator()(D3DXCOLOR const&a, D3DXCOLOR const& b) const { … } 
}; 

std::map<D3DXCOLOR, ID3DXMesh*, D3DXCOLOR_less> foo; 

這絕對是我會做什麼在這種情況下,除非你還需要operator <這個類在其他情況下。

0

定義operator<功能D3DXCOLOR,因爲

bool operator<(const D3DXCOLOR &c1, const D3DXCOLOR &c2) 
{ 
    return <some boolean value>; 
} 

或定義比較函子,一種叫D3DXCOLOR_LESS,並把它作爲第三個參數std::map

struct D3DXCOLOR_LESS 
{ 
    bool operator()(const D3DXCOLOR &c1, const D3DXCOLOR &c2) 
    { 
     return <some boolean value>; 
    } 
}; 

std::map<D3DXCOLOR, ID3DXMesh*, D3DXCOLOR_LESS> colormap; 
+0

這將會嚴重影響'operator <'的含義,因爲沒有一種方法可以在一行中排列顏色。 – ony 2011-03-09 11:42:35

+0

@ony:你的意思是*運營商的意思是什麼* *?無論你在'operator()'中寫什麼,都可以在'operator <'中寫入。有什麼大不了的? – Nawaz 2011-03-09 11:44:30

+0

':: D3DXCOLOR_myorder :: operator(..)'和':: operator <(..)'之間的區別在於最後一個是全局符號。所以如果一些圖書館會用這個算子來決定顏色如何形成集羣,那麼你會使兩個算法緊密結合在一起,而沒有任何有意義的關係。並且沒有理由將std :: map變體的排序作爲默認/常規/主要。 – ony 2011-03-10 15:17:45

0

其實RGBA顏色有沒有像任何標量一樣的默認準順序。你不應該在全局上下文中定義一個,但是你可以定義你自己的順序並在std :: map模板實例中指定它。請參閱http://www.sgi.com/tech/stl/Map.html的參數說明