2011-03-09 97 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的参数说明