STL for_eachは引数リストについて不平を言っています
質問
宿題の一部として、マップ内の各キャラクターの発生をマッピングすることになっています。私たちの関数は、STD :: for_eachを使用し、評価されるキャラクターに渡されることになっています。
私の機能は次のとおりです。
std::for_each(document_.begin(),
document_.end(),
std::mem_fun(&CharStatistics::fillMap));
document_
aです string
, 、およびfillMap関数は次のように定義されています
void CharStatistics::fillMap(char ch)
{
ch = tolower(ch);
++chars_.find(ch)->second;
}
chars_
として宣言されています std::map<char, unsigned int> chars_;
.
私はこれが機能するはずだと思いますが、コンパイラーは不平を言っています
error C2064: term does not evaluate to a function taking 1 arguments
引数リストを見ると私を混乱させます
_Fn1=std::mem_fun1_t<void,CharStatistics,char>,
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Alloc=std::allocator<char>,
1> _Result=void,
1> _Ty=CharStatistics,
1> _Arg=char,
1> _InIt=std::_String_iterator<char,std::char_traits<char>,std::allocator<char>>
それは私にはうまく見えます。 _elemはcharであり、私の関数はcharを受け入れます。イテレーターはaに他なりません char *
私は何が間違っているのですか?
解決
CharStatistics::fillMap
1つの引数を取る関数ではありません。メンバー関数なので、暗黙の最初の引数 - クラスインスタンスへのポインターがあります。
コード:
std::for_each(document_.begin(),
document_.end(),
std::mem_fun(&CharStatistics::fillMap));
for_each
どのインスタンスに電話したいのかわからない CharStatistics::fillMap
, 、あなたはそれを指定しませんでした。 charstatisticsインスタンスでバインドする必要があります。
std::bind1st(std::mem_fun(&CharStatistics::fillMap), &char_statistics_instance)
他のヒント
document_は文字のコレクションですか?
しかし、機能はcharstatisticsのメンバー機能です!おそらく、あなたはcharstatisticsのメンバー関数からこれを呼んでいます。その場合、Boost :: Bindを使用して、許可されている場合は解決できます。
std::for_each( document_.begin(), document_.end(),
boost::bind( &CharStatistics::fillMap, this, _1 );
std :: bind1stを「this」で使用できます。
std::for_each( document_.begin(), document_.end(),
std::bind1st( std::mem_fun(&CharStatistics::fillMap), this ) );
実際には恐ろしく複雑です。だからこそ、新しいバインドがはるかに優れています!
Boost :: Bindを使用することが許可されていない場合、MEM_FUNソリューションが気に入らない場合は、Operator()をオーバーロードしてCHARを取得する独自のファンサーを書いてください。このような:
struct CharStatsFunctor
{
typedef std::map< char, size_t > map_type;
map_type & mapToFill;
explicit CharStatsFunctor( map_type & m ) : mapToFill( m ) {}
void operator()(char ch ) const
{
++mapToFill[ ::tolower( ch ) ];
}
};
ループ呼び出しで
std::for_each( document_.begin(), document_.end(), CharStatsFunctor( chars_ ) );
注意してくださいフィルマップ関数にエラーがあります。私が与えたソリューションは機能します。
基本的に間違っているのは、あなたのコンテナがバリュータイプを持っていることです char
, 、 と for_each
の議論を取る関数を期待します char
, 、 しかし std::mem_fun(&CharStatistics::fillMap)
のインスタンスを取る関数オブジェクトに評価します CharStatistics
(その後、電話します fillMap
)
単に機能を変更してみませんか:
void CharStatistics::fillMap(std::string const& str)
{
std::string::const_iterator it(str.begin()), end(str.end());
for(; it != end; ++it)
++chars_.find(tolower(*it))->second;
}
もしも CharStatistics::fillMap
静的なメンバー関数ではないので、呼び出しをインスタンスにバインドする必要があります。
CharStatistics instance;
std::for_each(
document_.begin(),
document_.end(),
std::bind1st(
&CharStatistics::fillMap,
&instance
)
);
さらに、静的なメンバー関数でない場合、実際には2つの引数があります。 1つ目は暗黙的です this
ポインター、2番目はです char
. 。したがって、使用して2つの引数をバインドする必要があります boost::bind
(また std::bind
C ++ 0xを使用している場合):
CharStatistics instance;
std::for_each(
document_.begin(),
document_.end(),
boost::bind(
&CharStatistics::fillMap,
&instance,
_1
)
);
for_each
これで表示されるはずです bind2nd
1つの引数を取る関数オブジェクトとしてのインスタンス(_1
)、インスタンスは自動的に渡されます。