Nathan
Nathan

Reputation: 157

std::find() can't compile with gcc

#include <iostream>
#include <array>

using namespace std;

int main()
{
    array<int, 5> a = {1,2,3,4,5};

    auto it = find(a.cbegin(), a.cend(), 3);
    cout << *it << endl;
    return 0;
} 

The program goes well using VS 2015, but fails to compile using gcc. Is the code wrong? The error message is:

error: no matching function for call to ‘find(std::array<int, 5ul>::const_iterator, std::array<int, 5ul>::const_iterator, int)’

Upvotes: 2

Views: 1807

Answers (1)

BoBTFish
BoBTFish

Reputation: 19757

You need to

#include <algorithm>

This is where std::find lives. It seems with MSVC you get it through some transitive include in <iostream> or <array>.

I'd also suggest qualifying the names of standard library components fully, such as std::array and std::find, rather than using namespace std;. See here or here. It makes it clear you are trying to use the standard library find, rather than something else.

It is good practice to check that your find actually found something, before trying to print it. If you tried to find a value that isn't there, then printing it would cause Undefined Behaviour, which is a Bad Thing.

auto it = std::find(a.cbegin(), a.cend(), 3);
if ( a.cend() == it ) {
    std::cout << "Couldn't find value!\n";
    return 1;
}
std::cout << *it << '\n';
return 0;

I'm also not a big fan of std::endl. Did you know it writes a '\n' and flushes the stream? A lot of people don't realise it does 2 things, which makes the intent of your code a lot less clear. When I read it, I don't know if the person who wrote it really did want to flush the stream, or just didn't know std::endl does that. I prefer to just use

std::cout << '\n';

, or if you really do want to manually flush the stream (unlikely), be explicit about it:

std::cout << '\n' << std::flush;

Upvotes: 5

Related Questions