not1, unary_negate and lambdas

41 views
Skip to first unread message

Fernando Pelliccioni

unread,
Sep 15, 2013, 7:25:12 PM9/15/13
to std-dis...@isocpp.org
Hi,

Suppose I want to write this function...

template < typename I, typename P >
// requires I is a InputIterator
//          P is a Predicate(ValueType(I))
bool all_of_negated( I f, I l, P p )
{
return std::all_of( f, l, std::not1(p) );
}


... and I want to use it in this way...

void foo()
{
vector<int> vi { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
bool aon = all_of_negated( begin(vi), end(vi), []( int x ) { return true; } );
}

The function all_of_negated is incorrect acording to the Standard (n3691) because std::unary_negate requires that its template parameter has a typedef named argument_type.
See...

20.10.8 Negators [negators]
1 Negators not1 and not2 take a unary and a binary predicate, respectively, and return their complements
(5.3.1).
template <class Predicate>
class unary_negate {
public:
explicit unary_negate(const Predicate& pred);
bool operator()(const typename Predicate::argument_type& x) const;
typedef typename Predicate::argument_type argument_type;
typedef bool result_type;
};


I believe that the standard does not define the requirements for Predicate
I have checked the "Elements of Programming" and "N3351 - A Concept Design for the STL". 
None of them require that Predicate contains argument_type.

Posible Solutions:

A. Not use not1

template < typename I, typename P >
// requires I is a InputIterator
//          P is a Predicate(ValueType(I))
bool all_of_negated( I f, I l, P p )
{
return std::all_of( f, l, [p]( typename I::value_type const& x ) { return !p(x); }  );
}


I don't like it. I want to use not1.

B. Redefine unary_negate

template <class Predicate>
class unary_negate {
public:
explicit unary_negate(const Predicate& pred);

template <typename T>
// requires P is a Predicate(T)
bool operator()(const T& x) const;

typedef bool result_type;
};

backward compatibility break?

C. Redefine unary_negate and use TypeTraits (or Concept) for Function Arguments?

template <class Predicate>
class unary_negate {
public:
explicit unary_negate(const Predicate& pred);
bool operator()(const typename argument<Predicate, 0>::type& x) const;
typedef typename argument<Predicate, 0>::type argument_type;
typedef bool result_type;
};

We have to create this kind of TypeTraits. 
Is it possible?

I'll stick with option B, and I think that all the requirements for argument_type, first_argument_type and second_argument_type should be removed from the Standard.
What do you think?

Kind regards,
Fernando Pelliccioni.

Ville Voutilainen

unread,
Sep 15, 2013, 7:40:12 PM9/15/13
to std-dis...@isocpp.org
On 16 September 2013 02:25, Fernando Pelliccioni <fpelli...@gmail.com> wrote:


I'll stick with option B, and I think that all the requirements for argument_type, first_argument_type and second_argument_type should be removed from the Standard.
What do you think?

I think this must be a trace of incomplete work in the library. In c++11, none of the typedefs are needed for anything,
with decltype and such facilities. See also
http://cplusplus.github.io/LWG/lwg-defects.html#2149
which seems to skim the surface of this issue.


Ville Voutilainen

unread,
Sep 15, 2013, 7:43:45 PM9/15/13
to std-dis...@isocpp.org

Fernando Pelliccioni

unread,
Sep 15, 2013, 9:20:36 PM9/15/13
to std-dis...@isocpp.org

--
 
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussio...@isocpp.org.
To post to this group, send email to std-dis...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.

Ville, thanks for the pointers!
 

Reply all
Reply to author
Forward
0 new messages