开发者

Resolving operator ambiguity

I have the following map type...

std::map<D3DXCOLOR, ID3DXMesh*>

During compilation, xfunctional complains that it cannot resolve an ambiguity regarding the key type;

error C2593: 'operator <' is ambiguous

The candidate operators detected by the compiler are as follows;

  1. built-in C++ operator<(DWORD, DWORD)
  2. built-in C++ operator<(FLOAT, FLOAT)
  3. built-in C++ operator<(D3DCOLORVALUE, D3DCOLORVALUE)

The D3DXCOLOR struct consists of 4 floats r, g, b, and a respectively but does not define a operator <. It does however provide cast开发者_StackOverflow社区 functions for DWORD FLOAT and D3DCOLORVALUE, hence the entries in the candidate list.

I am contemplating the best way to resolve this problem. I could write my own inline operator for D3DXCOLOR, wrap the colour inside a new class which provides its own operator <, or is it possible to somehow hint to the compiler which implementation should be chosen from the list of candidates? The DWORD operator < would meet my requirements adequately.


You have three options. Supposing for example that you want them compared as colorvalues:

1) Define operator<:

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

2) Specialize 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) Supply a third template parameter to your map - note that this changes the type of the map, so if you pass the map around a lot this might be inconvenient. But it expresses that the ordering is to be used only for this map, not as the canonical "correct" order of colors for any other purpose.

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

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


You can just pass a less-than functor to the map class template that should be used.

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

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

This is definitely what I would do in this case, unless you also need the operator < for this class in other cases.


You'll need to write your own operator<, or provide a comparator functor to the map.

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;


Define operator< function for D3DXCOLOR, as

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

Or define a compare functor, something called D3DXCOLOR_LESS and pass it as third parameter to the std::map:

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

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


Actually RGBA color have no some default quasi-order like any scalar. And you shouldn't define one in global context, but you can define your own ordering and specify it in std::map template instance. See parameters description at http://www.sgi.com/tech/stl/Map.html

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜