Ошибка Visual Studio 2008 в & lt; алгоритме & gt ;? включает в себя алгоритм кажется непреднамеренно поменять местами порядок итераторов в строке 3795

Я пытаюсь получить includes алгоритм работы на set а также map сравнивая ключи карты со значениями набора. Проблема, которую необходимо обойти, — это, конечно, map<K,V>::value_type является pair<K,V> в то время как set<V>::value_type является V так что они не будут работать по умолчанию includes predicate<T> который ожидает один и тот же тип значения для обоих аргументов.

Поэтому я пишу следующие классы предикатов, чтобы обойти это

template <class P,class K>
struct mapKey_set_less : public std::binary_function<P,K,bool>
{
inline bool operator() (const P& x, const K& y) const {return x.first < y ;};
};

template <class K,class P>
struct set_mapKey_less : public std::binary_function<K,P,bool>
{
inline bool operator() (const K& x, const P& y) const {return x < y.first ;};
};

Однако экземпляр шаблона запускается в строке 313 файла xutility VS2008.

if (!_Pred(_Left, _Right))

с сообщением, что он не может преобразовать параметр 1 из const V в const std::pair<_Ty1,_Ty2>

Кажется, это вызвано строкой 3795 файла

if (_DEBUG_LT_PRED(_Pred, *_First2, *_First1))

где первый и второй аргументы, похоже, поменялись местами
Компиляция в Release Configuration выдает ту же ошибку в строке 3795, так что, похоже, реализация Visual Studio хочет, чтобы вы проходили этот код, если вы не повозитесь с каким-либо переключателем (если он есть), удаляющим этот макрос _DEBUG_LT_PRED.

Мой вопрос:
Это ошибка в Visual Studio или есть причина для этого, и я делаю ошибку? Я не делал C ++ более десяти лет, и на прошлой неделе мне пришлось взять курс на ускорение в некоторых трудных циклах, поэтому мне нужна вся помощь, которую я могу получить.

Спасибо всем

Ницца,

Я не думал о требованиях алгоритма. Имеет смысл проверить «меньше чем» с обеих сторон.

Не получая много радости, получая это для компиляции.

С моим предыдущим кодом

template <class P,class K>
struct mapKey_set_cmp //: public std::binary_function<P,K,bool>
{
inline bool operator() (const P& x, const K& y) const {return x.first < y ;};
};

Я получал

error C2664: 'bool mapKey_set_cmp<P,K>::operator ()(const P &,const K &) const' :
cannot convert parameter 1 from 'const double' to 'const std::pair<_Ty1,_Ty2> &'

что имеет смысл, так как нет оператора (), который может принимать double в качестве 1-го аргумента.

С дополнительным перегруженным оператором ()

template <class P,class K>
struct mapKey_set_cmp //: public std::binary_function<P,K,bool>
{
inline bool operator() (const P& x, const K& y) const {return x.first < y ;};
inline bool operator() (const K& x, const P& y) const {return x < y.first ;};
};

Я сейчас получаю

error C2664: 'bool mapKey_set_cmp<P,K>::operator ()(const K &,const P &) const' :
cannot convert parameter 1 from 'const std::pair<_Ty1,_Ty2>' to 'const double &'

error C2664: 'bool mapKey_set_cmp<P,K>::operator ()(const K &,const P &) const' :
cannot convert parameter 1 from 'const std::pair<_Ty1,_Ty2>' to 'const double &'

error C2664: 'bool mapKey_set_cmp<P,K>::operator ()(const K &,const P &) const' :
cannot convert parameter 2 from 'const double' to 'const std::pair<_Ty1,_Ty2> &'

error C2664: 'bool mapKey_set_cmp<P,K>::operator ()(const K &,const P &) const' :
cannot convert parameter 2 from 'const double' to 'const std::pair<_Ty1,_Ty2> &'

Следует отметить, что все ошибки, кажется, относятся ко 2-му operator()один с K 1-й и P Второй. И да, ни одно из упомянутых преобразований не должно быть возможным для этого оператора. Но почему компилятор не пытается использовать другой оператор? то есть тот, на котором эти преобразования должны быть разрешены. (Кстати, ошибки повторяются, потому что каждый из них возникает на двух разных строках, если вам интересно)

Другое дело, что это может быть, конечно же, неверная константность. Это было какое-то время, поэтому я постараюсь обдумать это до конца.

Спасибо за помощь

Изменить 15 мая 2013 г.

Мне пришлось «покончить с этим», чтобы обойти эту проблему, поместив ключи моей карты в набор, чтобы я мог вызвать includes Алгоритм на двух подходах (влечет за собой очевидное снижение производительности). Я все еще хотел бы решить это правильно, хотя. Вот весь код, необходимый для репликации ошибки компилятора, которую я описываю в Visual Studio 2008

template <class PAIR,class KEY>
struct mapKey_set_less : public std::binary_function<PAIR,KEY,bool>
{
inline bool operator() (const PAIR& x, const KEY& y) const {return x.first < y ;};
inline bool operator() (const KEY& x, const PAIR& y) const {return x < y.first ;};
};

int _tmain(int argc, _TCHAR* argv[])
{
map<string,double> theMap;
theMap["arse"] = 1;

set<string> theSet;
theSet.insert("arse");

typedef map<string,double>::iterator MI;
MI mi(theMap.begin()), miend(theMap.end());

typedef set<string>::iterator SI;
SI si(theSet.begin()), siend(theSet.end());

typedef mapKey_set_less< pair<string,double>,string> cmp;

if (includes(mi,miend,si,siend,cmp()))
{}

}

Компилятор выплевывает

Error   1   error C2664: 'bool mapKey_set_less<PAIR,KEY>::operator ()(const KEY &,const PAIR &) const' : cannot convert parameter 1 from 'std::pair<_Ty1,_Ty2>' to 'const std::string &'    c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility  346
Error   2   error C2664: 'bool mapKey_set_less<PAIR,KEY>::operator ()(const KEY &,const PAIR &) const' : cannot convert parameter 1 from 'std::pair<_Ty1,_Ty2>' to 'const std::string &'    c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility  348
Error   3   error C2664: 'bool mapKey_set_less<PAIR,KEY>::operator ()(const KEY &,const PAIR &) const' : cannot convert parameter 2 from 'std::basic_string<_Elem,_Traits,_Ax>' to 'const std::pair<_Ty1,_Ty2> &'   c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility  346
Error   4   error C2664: 'bool mapKey_set_less<PAIR,KEY>::operator ()(const KEY &,const PAIR &) const' : cannot convert parameter 2 from 'std::basic_string<_Elem,_Traits,_Ax>' to 'const std::pair<_Ty1,_Ty2> &'   c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility  348

Глядя только на 1-ю ошибку, кажется, что она хочет использовать operator () (KEY, PAIR) для передачи PAIR, KEY. Почему игнорируется доступный оператор () (PAIR, KEY) ???
Все другие ошибки находятся в том же духе, компилятор «появляется», чтобы игнорировать превосходно перегруженный оператор

Спасибо всем за помощь

3

Решение

Стандарт не требует, чтобы объекты из первого диапазона передавались только в качестве левого аргумента функции сравнения, а объекты во втором диапазоне передавались только в качестве правого аргумента. Итак, то, что делает Visual Studio, совершенно правильно и часто необходимо (см. Ниже).

Что вы можете сделать, это написать единственный функтор, который обрабатывает оба случая:

template <class K,class P>
struct set_mapKey_less : public std::binary_function<K,P,bool>
{
inline bool operator() (const K& x, const P& y) const {return x < y.first;};
inline bool operator() (const P& y, const K& x) const {return y.first < x; }
};
...
std::map<int,int> m;
std::set<int> s;

std::includes(m.begin(), m.end(), s.begin(), s.end(),
set_mapKey_less<int,std::pair<int const,int> >());

Чтобы понять, почему может потребоваться проверка, выполняемая VS, рассмотрите следующее:

set X = { 1000, 3000, 5000, 7000, 9000 }
map Y = { (3000,'a') }

Как вы собираетесь проверить, содержит ли X Y, если все, что у вас есть, это оператор меньше чем, который принимает парное значение слева и целое число справа?

Is (3000,'a').first < 1000? No.
Is (3000,'a').first < 3000? No.
Is (3000,'a').first < 5000? Yes.

На данный момент мы знаем, что (3000,'a').first, если в наборе, должно быть 3000. Но как мы можем проверить, что это на самом деле 3000 с компаратором, который может взять только пару на левой стороне? Если мы можем изменить аргументы, мы можем сделать это:

Is 3000 < (3000,'a').first? No.

Итак, теперь мы знаем, что 3000 не менее чем (3000,'a').first, а также (3000,'a').first не менее чем 3000поэтому они должны быть равны.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]