#include <cstdlib>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
    string foo = "123";

    if(count_if(foo.begin(), foo.end(), isdigit) == foo.size())
    {
        cout << "\nGreat!\n";
    }
    
    cin.get()
}

Does not work on bloodshed v4.9.9.2!!!
It outputs the following error:

no matching function for call to `count_if(__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, <unknown type>)'

But it does work on VC++ Express 2005... (obviously including stdafx.h)

I'm surprised that it even compiled on VC++ with a mistake like this:

cin.get()
}

You also might want to read this:
http://www.sgi.com/tech/stl/count_if.html

The new count interface uses the iterator_traits class, which relies on a C++ feature known as partial specialization. Many of today's compilers don't implement the complete standard; in particular, many compilers do not support partial specialization. If your compiler does not support partial specialization, then you will not be able to use the newer version of count, or any other STL components that involve iterator_traits.

I'm using g++, and it supports neither count() nor count_if() .

#include <cstdlib>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
    string foo = "123";

    if(count_if(foo.begin(), foo.end(), isdigit) == foo.size())
    {
        cout << "\nGreat!\n";
    }
    
    cin.get()
}

Does not work on bloodshed v4.9.9.2!!!
It outputs the following error:


But it does work on VC++ Express 2005... (obviously including stdafx.h)

If you don't mind satisfying my curiosity, does this work in Bloodshed?

#include <cstdlib>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

struct predicate {
    int operator()( int x ) { return isdigit( x ); }
};
 
int main()
{
    string foo = "123";
 
    if(count_if(foo.begin(), foo.end(), predicate()) == foo.size())
    {
        cout << "\nGreat!\n";
    }
    
    cin.get();
}

I'm surprised that it even compiled on VC++ with a mistake like this:

cin.get()
}

You also might want to read this:
http://www.sgi.com/tech/stl/count_if.html

I'm using g++, and it supports neither count() nor count_if() .

That was my mistake when pasting the code and editing the code tags, sorry for any confusion ;).


And yes, that code works, mind to explain the structure please?

And yes, that code works, mind to explain the structure please?

Hmm, I'm not sure I can explain it in a clear way because this is a subtle and tricky problem. Put simply, my hunch was that the problem came from your use of isdigit() directly as a template argument type.

If your compiler declares a library function with C linkage, like isdigit() in this case, you can't use it as a template argument type because functions with C++ linkage are expected. The linkage difference includes things like name mangling that make a function with C linkage hard to use safely, so I guess they just don't allow it. :) My solution was to create a function object with guaranteed C++ linkage and have it return a call to isdigit().

There's nothing special about a structure, anything that forces C++ linkage to a function-like thing works just as well. You could also do it with just a regular C++ function for example.

#include <cstdlib>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int predicate( int x )
{
    return isdigit( x );
}
 
int main()
{
    string foo = "123";
 
    if(count_if(foo.begin(), foo.end(), predicate) == foo.size())
    {
        cout << "\nGreat!\n";
    }
    
    cin.get();
}

In a perfect world, the reason VC++ worked fine is because isdigit() is declared with C++ linkage for that example. Here in the real world, VC++ probably just got it wrong. ;)

Oh, and isdigit() is declared in <cctype>, not <cstdlib>.

Comments
Didn't know that. Good post -Niek E
This article has been dead for over six months. Start a new discussion instead.