マップのキーをセットの値と比較することで、includes
アルゴリズムを動作させようとしています。回避する必要がある問題はもちろん、それはwhileであるため、両方の引数に同じ値の型を期待するデフォルトでは機能しません。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 ;};
};
ただし、VS2008 xutility ファイルの 313 行目でテンプレート インスタンシエーターがスローされます。
if (!_Pred(_Left, _Right))
const V
パラメータ1をからに変換できないというメッセージが表示されますconst std::pair<_Ty1,_Ty2>
これは、ファイルの 3795 行目で発生しているようです。
if (_DEBUG_LT_PRED(_Pred, *_First2, *_First1))
最初と 2 番目の引数が交換されているように見えるリリース構成でコンパイルすると、3795 行目で同じエラーが発生するため、Visual Studio の実装では、スイッチ (存在する場合) をいじらない限り、このコードを実行する必要があるようです。 _DEBUG_LT_PRED' マクロ。
私の質問は次のとおりです。これは Visual Studio のバグですか、それともこのような理由があり、間違いを犯していますか? 私は 10 年以上 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> &'
第 1 引数として double を取ることができる operator() がないため、これは理にかなっています。
追加のオーバーロードされた operator() を使用
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
2 番目のものを参照しているように見えることです。そして、はい、言及されている変換はどれも、その演算子では可能であってはなりません。しかし、なぜコンパイラは他の演算子を試さないのでしょうか? つまり、それらの変換が許可されるべきものです。(ところで、疑問に思っている場合に備えて、エラーはそれぞれ2つの異なる行で発生するため、繰り返されます)
これが考えられるもう1つのことは、もちろんconstの不正確さです。長くなりましたので、じっくり考えてみたいと思います。
助けてくれてありがとう
2013 年 5 月 15 日に編集
私は「それをやり遂げる」必要があったので、includes
2 つのセットでアルゴを呼び出すことができるように、マップ キーをセットに入れることでこの問題を回避しました (明らかなパフォーマンス ペナルティが発生しました)。私はまだこれを適切に解決したいと思っています。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
最初のエラーだけを見ると、operator()(KEY,PAIR) を使用して PAIR,KEY を渡したいようです。利用可能な operator()(PAIR,KEY) を無視するのはなぜですか??? 他のエラーはすべて同じ傾向にあります。コンパイラは、完全に適切なオーバーロードされた演算子を無視するように「見えます」
助けてくれてありがとう