Natknąłem się na dziwny problem kompilacji. Chcę przetworzyć listę ciągów, używając std::for_each
. Poniższy kod ilustruje uproszczony problem:std :: for_each ignorowanie argumentu funkcji domyślnej
# include <list>
# include <string>
# include <algorithm>
using namespace std ;
void f(wstring & str)
{
// process str here
}
void g(wstring & str, int dummy = 0)
{
// process str here, same as f, just added a second default dummy argument
}
int main(int, char*[])
{
list<wstring> text ;
text.push_back(L"foo") ;
text.push_back(L"bar") ;
for_each(text.begin(), text.end(), f) ; // OK, fine :)
for_each(text.begin(), text.end(), g) ; // Compilation error, complains about
// g taking 2 arguments, but called within std::for_each
// with only one argument.
// ...
return 0 ;
}
testowałem przy użyciu MinGW 4.5.2 i MSVC10, zarówno zgłoszone ten sam komunikat o błędzie. Pierwotnie chciałem użyć boost::algorithm::trim
jako funkcji przetwarzania przekazanej do std::for_each
, ale odkryłem, że wymaga ona dwóch argumentów, z których pierwszy jest obowiązkowy (ciąg do przetworzenia), a drugi jest opcjonalny (ustawienie regionalne określające definicję znaków spars) .
Czy istnieje sposób na zachowanie czystości podczas korzystania z funkcji std::for_each
(i innych standardowych algorytmów) w przypadku funkcji lub metod z domyślnymi argumentami? Znalazłem sposób, aby to działało, ale to nie jest bardziej jasne i zrozumiałe, a więc for
pętla zaczyna wydawać się łatwiejsze ...
# include <list>
# include <string>
# include <algorithm>
# include <boost/bind.hpp>
# include <boost/algorithm/string.hpp>
using namespace std ;
using namespace boost ;
// ... somewhere inside main
list<wstring> text ;
for_each(text.begin(), text.end(), bind(algorithm::trim<wstring>, _1, locale()) ;
// One must deal with default arguments ...
// for_each(text.begin(), text.end(), algorithm::trim<wstring>) would be a real pleasure
dzięki za pomoc!
Uwaga: Właśnie rozpoczął naukę angielskiego, przepraszam za błędy :)
Myślę, że po prostu nie działa w ten sposób dla funktorów. Usuń atrapę z argumentu. –
Argumentem sztucznym dodanym do 'g' było zademonstrowanie dziwnego zachowania' std :: for_each'. Wywołanie 'g' z jakimś' wstring str' jak 'g (str)' działa jak znak uroku, ale nie wewnątrz 'std :: for_each'. W moim przypadku użycie 'boost :: algorithm :: trim' bezpośrednio jako funktora jest niemożliwe bez lew, ponieważ jego drugi argument jest opcjonalny (std :: locale) – overcoder
@ Overwerk: to dlatego, że' g (str) 'natychmiast staje się 'g (str, 0)' - domyślnym argumentem jest po prostu cukier generujący kod. –