Устранение неоднозначности оператора - PullRequest
4 голосов
/ 09 марта 2011

У меня есть следующий тип карты ...

std::map<D3DXCOLOR, ID3DXMesh*>

Во время компиляции xfunctional жалуется, что не может устранить неоднозначность относительно типа ключа;

error C2593: 'operator <' is ambiguous

Операторы-кандидаты, обнаруженные компилятором, следующие:

  1. встроенный оператор C ++ <(DWORD, DWORD) </li>
  2. встроенный оператор C ++ <(FLOAT, FLOAT) </li>
  3. встроенный оператор C ++ <(D3DCOLORVALUE, D3DCOLORVALUE) </li>

Структура D3DXCOLOR состоит из 4 чисел с плавающей запятой r , g , b и a соответственно, но не определяет оператор < , Однако он предоставляет функции приведения для DWORD FLOAT и D3DCOLORVALUE, следовательно, записей в списке кандидатов.

Я обдумываю лучший способ решить эту проблему. Я мог бы написать свой собственный встроенный оператор для D3DXCOLOR, обернуть цвет внутри нового класса, который предоставляет свой собственный оператор <, или можно как-то намекнуть компилятору, какую реализацию следует выбрать из списка кандидатов? Оператор DWORD <удовлетворит мои требования. </p>

Ответы [ 5 ]

3 голосов
/ 09 марта 2011

У вас есть три варианта. Предположим, например, что вы хотите, чтобы они сравнивались как цветовые значения:

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>
2 голосов
/ 09 марта 2011

Вы можете просто передать функтор меньше, чем шаблон класса map, который следует использовать.

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

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

Это определенно то, что я бы сделал в этом случае, если только вам не нужен operator < для этого класса в других случаях.

0 голосов
/ 09 марта 2011

На самом деле цвета RGBA не имеют квази-порядка по умолчанию, как у любого скаляра. И вы не должны определять его в глобальном контексте, но вы можете определить свой собственный порядок и указать его в экземпляре шаблона std :: map. См. Описание параметров на http://www.sgi.com/tech/stl/Map.html

0 голосов
/ 09 марта 2011

Определите функцию 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 голосов
/ 09 марта 2011

Вам нужно написать свой собственный оператор <или предоставить функтор сравнения на карту. </p>

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;
...