The Linux Page

error: no matching function for call to 'find()'

Find the Frog! (Many frogs sculptures on a mini-bench in various position such as kissing, taking a bath, dancing...)

Problem

Today, I got a rather weird C++ error. That is. My code is very simply doing a search using the std::find() function as follow:

    auto it(std::find(
          headers.cbegin()
        , headers.cend()
        , column_name));

Yet, it would not compile that simple line of  code.

Clearly, I use the begin() and end() of the same vector, and I use a value which is exactly what the vector is made of (we see that in the first line of error below: the std::vector<> T parameter is a basic string, which is what column_name is.)

Looking at the error, we see that it says that it's just not compatible. It expects an std::istreambuf_iterator. Why would C++ tell me that such a type is required when I used a parameter to the function which is an std::vector.

[  5%] Building CXX object src/CMakeFiles/addr.dir/route.cpp.o
/home/snapwebsites/snapcpp/contrib/libaddr/src/route.cpp: In function ‘int addr::{anonymous}::get_position(const words_t&, const string&)’:
/home/snapwebsites/snapcpp/contrib/libaddr/src/route.cpp:113:22: error: no matching function for call to ‘find(std::vector<std::__cxx11::basic_string<char> >::const_iterator, std::vector<std::__cxx11::basic_string<char> >::const_iterator, const string&)’
         , column_name));
                      ^
In file included from /usr/include/c++/5/bits/locale_facets.h:48:0,
                 from /usr/include/c++/5/bits/basic_ios.h:37,
                 from /usr/include/c++/5/ios:44,
                 from /usr/include/c++/5/istream:38,
                 from /usr/include/c++/5/fstream:38,
                 from /home/snapwebsites/snapcpp/contrib/libaddr/src/route.cpp:41:
/usr/include/c++/5/bits/streambuf_iterator.h:369:5: note: candidate: template<class _CharT2> typename __gnu_cxx::__enable_if<std::__is_char<_CharT2>::__value, std::istreambuf_iterator<_CharT> >::__type std::find(std::istreambuf_iterator<_CharT>, std::istreambuf_iterator<_CharT>, const _CharT2&)
     find(istreambuf_iterator<_CharT> __first,
     ^
/usr/include/c++/5/bits/streambuf_iterator.h:369:5: note:   template argument deduction/substitution failed:
/home/snapwebsites/snapcpp/contrib/libaddr/src/route.cpp:113:22: note:   ‘__gnu_cxx::__normal_iterator<const std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >’ is not derived from ‘std::istreambuf_iterator<_CharT>’
         , column_name));
                      ^
src/CMakeFiles/addr.dir/build.make:158: recipe for target 'src/CMakeFiles/addr.dir/route.cpp.o' failed

If you think that this error is not talkative, welcome to the club! It took me a moment to find the reason for the problem...

Solution

The fact is that this problem is caused by the missing definition of the default std::find() function. What was needed in that C++ file was a #include of the algorithms. The following:

#include <algorithm>

In fact, I had the input stream included, so the following:

#include <ifstream>

And it looks like they have a specialization of the std::find() algorithm for one to search through it stream buffer. That definition gets picked up if you have only that one include.

By adding the other include, now C++ is capable of finding a matching std::find() and compiles my file happily.

If you're interested about finding the list of routes on your Linux OS using a C++ class, I have that in my libaddr library.