Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can I not pass to_lower_copy directly to transform instead of wrapping it in a lambda?

Tags:

c++

boost

I'm trying to use boost::to_lower_copy and std::transform to lower-case a bunch of strings. As below, Variant 1, using a lamdba works; Variant 2 also works demonstrating that that's the right template-overload the compiler picks. But the lambda is silly – all it does is forward the single argument along to boost::to_lower_copy. But Variant 3, using the function template directly doesn't compile, even if I instantiate it. What am I missing?

I have clang version 3.3 (tags/RELEASE_33/rc3), using libstdc++-4.8.1-1.fc19.i686 and 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(
^
like image 868
Ambarish Sridharanarayanan Avatar asked Oct 02 '13 20:10

Ambarish Sridharanarayanan


1 Answers

Default function arguments.

boost::to_lower_copy has a 3 argument and 2 argument version. The 2 argument version, which you are instantiating, has a default argument. So when called directly, you do not need to provide it, it is provided implicitly.

The function pointer to to_lower_copy does not, however, package the fact there is a default argument.

like image 140
Yakk - Adam Nevraumont Avatar answered Oct 29 '22 10:10

Yakk - Adam Nevraumont