2013-10-02 14 views
5

Próbuję użyć boost :: to_lower_copy i std :: transform na małe litery kilka ciągów. Jak poniżej, Wariant 1, używając Lamdba działa; Wariant 2 również działa, demonstrując, że jest to właściwy szablon - przeciążaj wybory kompilatora. Ale lambda jest głupia - wszystko, co robi, to przekazywanie pojedynczego argumentu, aby zwiększyć :: to_lower_copy. Ale Wariant 3, korzystając bezpośrednio z szablonu funkcji, nie kompiluje się, nawet jeśli go utworzę. czego mi brakuje?Dlaczego nie można przekazać parametru to_lower_copy bezpośrednio w celu przekształcenia zamiast jego zawijania w lambda?

Posiadam wersję językową 3.3 (tagi/RELEASE_33/rc3), używając libstdC++ - 4.8.1-1.fc19.i686 i boost-1.53.0-14.fc19.i686.

vector<string> strings = {"Foo", "Bar"}; 
vector<string> lower_cased_strings; 
transform(
    strings.begin(), 
    strings.end(), 
    inserter(lower_cased_strings, lower_cased_strings.end()), 
// Variant 1 
// [](const string &word) { 
//  return boost::to_lower_copy(word); 
// } 
// Variant 2 
// [](const string &word) { 
//  return boost::to_lower_copy<string>(word); 
// } 
// Variant 3 
    boost::to_lower_copy<string> 
    ); 

> clang++ -std=c++11 lowercase.cxx 

In file included from lowercase.cxx:3: 
In file included from /usr/include/boost/algorithm/string.hpp:18: 
In file included from /usr/include/boost/algorithm/string/std_containers_traits.hpp:23: 
In file included from /usr/include/boost/algorithm/string/std/slist_traits.hpp:16: 
In file included from /usr/lib/gcc/i686-redhat-linux/4.8.1/../../../../include/c++/4.8.1/ext/slist:47: 
In file included from /usr/lib/gcc/i686-redhat-linux/4.8.1/../../../../include/c++/4.8.1/algorithm:62: 
/usr/lib/gcc/i686-redhat-linux/4.8.1/../../../../include/c++/4.8.1/bits/stl_algo.h:4949:33: error: too few arguments to function call, expected 2, have 1 
     *__result = __unary_op(*__first); 
       ~~~~~~~~~~  ^
lowercase.cxx:11:5: note: in instantiation of function template specialization 'std::transform<__gnu_cxx::__normal_iterator<std::basic_string<char> *, std::vector<std::basic_string<char>, 
    std::allocator<std::basic_string<char> > > >, std::insert_iterator<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > >, std::basic_string<char> (*)(const std::basic_string<char> 
    &, const std::locale &)>' requested here 
transform(
^ 
+1

Spróbuj przekazać go przez std :: bind() lub boost :: bind() – Slava

+1

Tak, to też działa, ale bind vs. lambda to pranie, IMO. –

Odpowiedz

5

Domyślne argumenty funkcji.

boost::to_lower_copy ma 3 argumenty i 2 wersje argumentów. Wersja 2-argumentowa, którą tworzysz, ma domyślny argument. Tak więc, gdy zostanie wywołany bezpośrednio, nie trzeba go podawać, jest on podawany niejawnie.

Wskaźnik funkcji na to_lower_copy nie pakuje jednak faktu, że istnieje domyślny argument.

+1

@Slava Tak, robi: [przykład] (http://coliru.stacked-crooked.com/a/1136206601d880cc) – jrok

+0

Dzięki, TIL. Czy istnieje czysty sposób pakowania argumentu domyślnego? Mógłbym użyć binda, przypuszczam, ale to wydaje się równie niepewne. A może twój sędzia, że ​​lambda jest najmniej brzydka? –

+1

@AmbarishSridharanarayanan just lambda it. # 2 w mojej opinii. Jeśli jesteś zdenerwowany przez lambdę, odłóż ją poza linię ('auto boost_to_lower = [] ...') z komentarzem informującym, dlaczego tak jest. Mógłbym kontynuować propozycję dodania przesłonięcia obiektów set do C++, ale to nie jest ani tutaj, ani tam. – Yakk

Powiązane problemy