Hi,
Following this question: How to negate a predicate function using operator ! in C++?
I want to create an operator ! can work with any functor that inherited from unary_function. I tried:
template<typename T>
inline std::unary_negate<T> operator !( const T& pred ) {
return std::not1( pred );
}
The compiler complained:
Error 5 error C2955: 'std::unary_function' : use of class template requires template argument list c:\program files\microsoft visual studio 10.0\vc\include\xfunctional 223 1 Graphic
Error 7 error C2451: conditional expression of type 'std::unary_negate<_Fn1>' is illegal c:\program files\microsoft visual studio 10.0\vc\include\ostream 529 1 Graphic
Error 3 error C2146: syntax error : missing ',' before identifier 'argument_type' c:\program files\microsoft visual studio 10.0\vc\include\xfunctional 222 1 Graphic
Error 4 error C2065: 'argument_type' : undeclared identifier c:\program files\microsoft visual studio 10.0\vc\include\xfunctional 222 1 Graphic
Error 2 error C2039: 'argument_type' : is not a member of 'std::basic_ostream<_Elem,_Traits>::sentry' c:\program files\microsoft visual studio 10.0\vc\include\xfunctional 222 1 Graphic
Error 6 error C2039: 'argument_type' : is not a member of 'std::basic_ostream<_Elem,_Traits>::sentry' c:\program files\microsoft visual studio 10.0\vc\include\xfunctional 230 1 Graphic
Any idea?
Update
Follow "templatetypedef" solution, I got new error:
Error 3 error C2831: 'operator !' cannot have default parameters c:\visual studio 2010 projects\graphic\graphic\main.cpp 39 1 Graphic
Error 2 error C2808: unary 'operator !' has too many formal parameters c:\visual studio 2010 projects\graphic\graphic\main.cpp 39 1 Graphic
Error 4 error C2675: unary '!' : 'is_prime' does not define this operator or a conversion to a type acceptable to the predefined operator c:\visual studio 2010 projects\graphic\graphic\main.cpp 52 1 Graphic
Update 1
Complete code:
#include <iostream>
#include <functional>
#include <utility>
#include <cmath>
#include <algorithm>
#include <iterator>
#include <string>
#include <boost/assign.hpp>
#include <boost/assign/std/vector.hpp>
#include <boost/assign/std/map.hpp>
#include <boost/assign/std/set.hpp>
#include <boost/assign/std/list.hpp>
#include <boost/assign/std/stack.hpp>
#include <boost/assign/std/deque.hpp>
struct is_prime : std::unary_function<int, bool> {
bool operator()( int n ) const {
if( n < 2 )
return 0;
if( n == 2 || n == 3 )
return 1;
if( n % 2 == 0 || n % 3 == 0 )
return 0;
int upper_bound = std::sqrt( static_cast<double>( n ) );
for( int pf = 5, step = 2; pf <= upper_bound; ) {
if( n % pf == 0 )
return 0;
pf += step;
step = 6 - step;
}
return 1;
}
};
/*
template<typename T>
inline std::unary_negate<T> operator !( const T& pred, typename T::argument_type* dummy = 0 ) {
return std::not1<T>( pred );
}
*/
inline std::unary_negate<is_prime> operator !( const is_prime& pred ) {
return std::not1( pred );
}
template<typename T>
inline void print_con( const T& con, const std::string& ms = "", const std::string& sep = ", " ) {
std::cout << ms << '\n';
std::copy( con.begin(), con.end(), std::ostream_iterator<typename T::value_type>( std::cout, sep.c_str() ) );
std::cout << "\n\n";
}
int main() {
using namespace boost::assign;
std::vector<int> nums;
nums += 1, 3, 5, 7, 9;
nums.erase( remove_if( nums.begin(), nums.end(), !is_prime() ), nums.end() );
print_con( nums, "After remove all primes" );
}
Thanks,
Chan Nguyen