次の動作で 2 つのマップを一緒に追加したいと考えています。
キーが存在する場合 -> 2 つのキー値を一緒に追加します。
キーが存在しない場合 -> ペアを挿入してマップします。
標準ライブラリのアルゴリズムをいくつか見てきました。つまり、変換しますが、私が望むことをしていないようです。
このリンクから取得
template < class InputIterator, class OutputIterator, class UnaryOperator >
OutputIterator transform ( InputIterator first1, InputIterator last1,
OutputIterator result, UnaryOperator op )
{
while (first1 != last1)
*result++ = op(*first1++); // or: *result++=binary_op(*first1++,*first2++);
return result;
}
ここからの私の考えは、使用時に2番目のマップからイテレータが1つしかないことと、適切なファンクタ
*result++=binary_op(*first1++,*first2++);
したがって、キー値を見つけるために 2 番目のマップをループすることはできません。
1つの考えは、微妙な変更を加えて独自のアルゴリズムを作成することだけでした.
template < class InputIterator, class ContainerType, class BinaryOperator >
void myTransform ( InputIterator first1, InputIterator last1,
ContainerType cont2,
BinaryOperator binary_op )
{
while (first1 != last1)
binary_op(first1++, cont2); //cont2 passed by reference
}
その後、次を使用できます。
cont2.find()
ファンクターでマップ全体を検索します。
これは私が考えていたことのより完全な例ですが、解決できないコンパイルエラーが発生したようです(BinaryOperatorタイプを推測しているようです...以下を参照)?
#include <map>
#include <string>
#include <iostream>
template < class InputIterator, class ContainerType, class BinaryOperator >
void myTransform ( InputIterator first1, InputIterator last1,
ContainerType &cont2,
BinaryOperator binary_op )
{
while (first1 != last1)
binary_op(first1++, cont2); //cont2 passed by reference
}
template<class IteratorType, class ContainerType>
struct AddMapValues:
std::binary_function<IteratorType, ContainerType, void>
{
void operator()(IteratorType itr, ContainerType& cont)
{
if( cont.find(itr->first) != cont.end() ) cont[itr->first] = cont.find(itr->first).second + itr->second;
else cont.insert( (*itr) );
}
};
int main()
{
typedef std::map<std::string, double> stringDoubleMap;
typedef std::map<std::string, double>::iterator stringDoubleMapItr;
typedef void (*ptrfnt)(stringDoubleMapItr, stringDoubleMap& );
stringDoubleMap map1;
stringDoubleMap map2;
map1.insert( stringDoubleMap::value_type("Test1",1.0) );
map1.insert( stringDoubleMap::value_type("Test2",2.0) );
map1.insert( stringDoubleMap::value_type("Test3",3.0) );
map2.insert( stringDoubleMap::value_type("Test1",1.0) );
map2.insert( stringDoubleMap::value_type("Test2",2.0) );
map2.insert( stringDoubleMap::value_type("Test3",3.0) );
myTransform( map1.begin(), map1.end(),
map2,
AddMapValues< stringDoubleMapItr, stringDoubleMap >() );
return 0;
}
ここに私のコンパイラエラーがあります:
testingMapTransforms.cxx: In function ‘int main()’:
testingMapTransforms.cxx:52:85: error: no matching function for call to ‘myTransform(std::map<std::basic_string<char>, double>::iterator, std::map<std::basic_string<char>, double>::iterator, stringDoubleMap&, std::map<std::basic_string<char>, double>::iterator, AddMapValues<std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, double> >, std::map<std::basic_string<char>, double> >)’
testingMapTransforms.cxx:52:85: note: candidate is:
testingMapTransforms.cxx:12:20: note: template<class InputIterator, class ContainerType, class OutputIterator, class BinaryOperator> OutputIterator myTransform(InputIterator, InputIterator, ContainerType, OutputIterator, BinaryOperator)
別のイテレータがどこかから来ているようで、コンテナの型が正しく読み取られていませんか?
何か案は?
私は使っている
gcc - GNU プロジェクトの C および C++ コンパイラ
と
Ubuntu/リナロ 4.6.3-1ubuntu5
ありがとう
ノート:
回答で上記のコードの動作バージョンを更新しました。代わりに質問コードを変更する必要があると思われる場合は、お知らせください。ベストプラクティスがわからない