STL transform algorithm

Discussion in 'C++' started by Patrick Guio, Nov 2, 2005.

  1. Patrick Guio

    Patrick Guio Guest

    Dear all,

    I am trying to use the std::transform algorithm to to the following

    vector< vector<char> >::iterator ik = keys.begin(); // key list iterator
    vector< vector<char> >::iterator is = ik; // save begin
    [snip]
    vector<char>::const_iterator i = ik->begin();
    vector<char>::const_iterator e = ik->end();
    vector<char>::iterator s = is->begin();
    for ( ; i != e; i++, s++) { // xor the key s = s ^ k
    *s ^= *i;
    }

    I wrote the binary operator xor

    template <class _Tp>
    struct logical_xor : public std::binary_function<_Tp, _Tp, bool>
    {
    bool
    operator()(const _Tp& __x, const _Tp& __y) const
    {
    return __x ^ __y;
    }
    };

    and call it into the transform algorithm

    // run through the ik iterator (input1) and is iterator (input2) and
    // return into is (output)
    std::transform(ik->begin(), ik->end(), is->begin(), is->begin(), logical_xor<byte>());

    But it does not seem to work correctly.
    Can input2 and output iterator be the same? (i.e. perform the operation
    (output =) input2 = op(input1, input2)
    Is there a way to perform operation and assignement ^= operator instead?
    (i.e. perform the operation (output =) input2 op= input1

    Sincerely,

    Patrick
     
    Patrick Guio, Nov 2, 2005
    #1
    1. Advertising

  2. Patrick Guio wrote:
    >
    > Dear all,
    >
    > I am trying to use the std::transform algorithm to to the following
    >
    > vector< vector<char> >::iterator ik = keys.begin(); // key list
    > iterator
    > vector< vector<char> >::iterator is = ik; // save begin
    > [snip]
    > vector<char>::const_iterator i = ik->begin();
    > vector<char>::const_iterator e = ik->end();
    > vector<char>::iterator s = is->begin();
    > for ( ; i != e; i++, s++) { // xor the key s = s ^ k
    > *s ^= *i;
    > }
    >
    > I wrote the binary operator xor
    >
    > template <class _Tp>
    > struct logical_xor : public std::binary_function<_Tp, _Tp, bool>
    > {
    > bool
    > operator()(const _Tp& __x, const _Tp& __y) const
    > {
    > return __x ^ __y;
    > }
    > };
    >
    > and call it into the transform algorithm
    >
    > // run through the ik iterator (input1) and is iterator (input2) and //
    > return into is (output)
    > std::transform(ik->begin(), ik->end(), is->begin(), is->begin(),
    > logical_xor<byte>());
    >
    > But it does not seem to work correctly.
    > Can input2 and output iterator be the same? (i.e. perform the operation
    > (output =) input2 = op(input1, input2)
    > Is there a way to perform operation and assignement ^= operator instead?
    > (i.e. perform the operation (output =) input2 op= input1
    >



    Just a question: What's the sense of assigning the (bool) result of x XOR y into x ?
    Or am I missing something?

    Stefan
    --
    Stefan Naewe
    naewe.s_AT_atlas_DOT_de
     
    =?ISO-8859-1?Q?Stefan_N=E4we?=, Nov 2, 2005
    #2
    1. Advertising

  3. On Wed, 2 Nov 2005 13:35:25 +0100, Patrick Guio <>
    wrote:

    >
    >Dear all,
    >
    >I am trying to use the std::transform algorithm to to the following
    >
    > vector< vector<char> >::iterator ik = keys.begin(); // key list iterator
    > vector< vector<char> >::iterator is = ik; // save begin
    > [snip]
    > vector<char>::const_iterator i = ik->begin();
    > vector<char>::const_iterator e = ik->end();
    > vector<char>::iterator s = is->begin();
    > for ( ; i != e; i++, s++) { // xor the key s = s ^ k
    > *s ^= *i;
    > }
    >
    >I wrote the binary operator xor
    >
    >template <class _Tp>
    >struct logical_xor : public std::binary_function<_Tp, _Tp, bool>
    >{
    > bool
    > operator()(const _Tp& __x, const _Tp& __y) const
    > {
    > return __x ^ __y;
    > }
    >};
    >
    >and call it into the transform algorithm
    >
    >// run through the ik iterator (input1) and is iterator (input2) and
    >// return into is (output)
    >std::transform(ik->begin(), ik->end(), is->begin(), is->begin(), logical_xor<byte>());
    >
    >But it does not seem to work correctly.
    >Can input2 and output iterator be the same? (i.e. perform the operation
    >(output =) input2 = op(input1, input2)
    >Is there a way to perform operation and assignement ^= operator instead?
    >(i.e. perform the operation (output =) input2 op= input1
    >
    >Sincerely,
    >
    >Patrick


    You cannot change either of the input vectors. The next-to-last
    argument should refer to another vector which is filled with the
    results of the logical_xor. So you need to initialize a third vector
    with the same size as the range you are working on (in this case,
    since you pass begin() and end(), the same size as the whole input
    vectors).

    Aside from that, you seem to have problems with the binary function.

    First of all, you should never use the names beginning with an
    underscore because these are reserved for the library.

    Secondly, your class inherits from a concrete specialization of a
    template class; it is not a template class!

    Thirdly, your function needs to return char (not bool), which is what
    the vectors are declared to contain.

    Something like this should work:

    struct logical_xor : public std::binary_function< char, char, char >
    {
    char operator()(const char& x, const char& y) const
    {
    return x ^ y;
    }
    };

    I didn't test this, however.

    --
    Bob Hairgrove
     
    Bob Hairgrove, Nov 2, 2005
    #3
  4. Bob Hairgrove wrote:
    > On Wed, 2 Nov 2005 13:35:25 +0100, Patrick Guio <>
    > wrote:
    >
    >
    >>Dear all,
    >>
    >>I am trying to use the std::transform algorithm to to the following
    >>
    >> vector< vector<char> >::iterator ik = keys.begin(); // key list iterator
    >> vector< vector<char> >::iterator is = ik; // save begin
    >> [snip]
    >> vector<char>::const_iterator i = ik->begin();
    >> vector<char>::const_iterator e = ik->end();
    >> vector<char>::iterator s = is->begin();
    >> for ( ; i != e; i++, s++) { // xor the key s = s ^ k
    >> *s ^= *i;
    >> }
    >>
    >>I wrote the binary operator xor
    >>
    >>template <class _Tp>
    >>struct logical_xor : public std::binary_function<_Tp, _Tp, bool>
    >>{
    >> bool
    >> operator()(const _Tp& __x, const _Tp& __y) const
    >> {
    >> return __x ^ __y;
    >> }
    >>};
    >>
    >>and call it into the transform algorithm
    >>
    >>// run through the ik iterator (input1) and is iterator (input2) and
    >>// return into is (output)
    >>std::transform(ik->begin(), ik->end(), is->begin(), is->begin(), logical_xor<byte>());
    >>
    >>But it does not seem to work correctly.
    >>Can input2 and output iterator be the same? (i.e. perform the operation
    >>(output =) input2 = op(input1, input2)
    >>Is there a way to perform operation and assignement ^= operator instead?
    >>(i.e. perform the operation (output =) input2 op= input1
    >>
    >>Sincerely,
    >>
    >>Patrick

    >
    >
    > You cannot change either of the input vectors. The next-to-last
    > argument should refer to another vector which is filled with the
    > results of the logical_xor. So you need to initialize a third vector
    > with the same size as the range you are working on (in this case,
    > since you pass begin() and end(), the same size as the whole input
    > vectors).



    From '25.2.3 Transform [lib.alg.transform]':

    ....
    5 Notes: result may be equal to first in case of unary transform, or to first1 or first2 in
    case of binary transform.



    > Aside from that, you seem to have problems with the binary function.
    >
    > First of all, you should never use the names beginning with an
    > underscore because these are reserved for the library.
    >
    > Secondly, your class inherits from a concrete specialization of a
    > template class; it is not a template class!
    >
    > Thirdly, your function needs to return char (not bool), which is what
    > the vectors are declared to contain.
    >


    ACK.


    Stefan
    --
    Stefan Naewe
    naewe.s_AT_atlas_DOT_de
     
    =?ISO-8859-1?Q?Stefan_N=E4we?=, Nov 2, 2005
    #4
  5. On Wed, 02 Nov 2005 14:28:21 +0100, Stefan Näwe <>
    wrote:

    >From '25.2.3 Transform [lib.alg.transform]':
    >
    >...
    >5 Notes: result may be equal to first in case of unary transform, or to first1 or first2 in
    > case of binary transform.


    Thanks for this. I'm glad to know that the standard allows it. I was
    reading documentation from an older version of MSDN, which I shouldn't
    have done...but I was too lazy to get my heavy standards book off the
    shelf! Now I'll know better

    Here's what the MSDN for VS 6.0 says:

    "transform
    template<class InIt, class OutIt, class Unop>
    OutIt transform(InIt first, InIt last, OutIt x, Unop uop);
    template<class InIt1, class InIt2, class OutIt, class Binop>
    OutIt transform(InIt1 first1, InIt1 last1, InIt2 first2,
    OutIt x, Binop bop);
    The first template function evaluates *(x + N) = uop(*(first + N))
    once for each N in the range [0, last - first). It then returns x +
    (last - first). The call uop(*(first + N)) must not alter *(first +
    N).

    The second template function evaluates *(x + N) = bop(*(first1 + N),
    *(first2 + N)) once for each N in the range [0, last1 - first1). It
    then returns x + (last1 - first1). The call bop(*(first1 + N),
    *(first2 + N)) must not alter either *(first1 + N) or *(first2 + N)."
    ^^^^^^^^^^^^^^

    I'm glad they have caught up with the standard here.

    --
    Bob Hairgrove
     
    Bob Hairgrove, Nov 2, 2005
    #5
  6. Patrick Guio wrote:

    > On Wed, 2 Nov 2005, Bob Hairgrove wrote:
    >
    > Hello Bob,
    >
    >
    >
    >> First of all, you should never use the names beginning with an
    >> underscore because these are reserved for the library.
    >>
    >> Secondly, your class inherits from a concrete specialization of a
    >> template class; it is not a template class!
    >>
    >> Thirdly, your function needs to return char (not bool), which is what
    >> the vectors are declared to contain.

    >
    > Oops my fault, I did grab the template class (too quickly obviously) from
    > logical_or in (||) <algorithm> which is not the bitwise or operator (|)
    >
    > I don't want to loose generality and it looks like it works well
    > with the following definition
    >
    > template <class _Tp>
    > struct logical_xor : public std::binary_function<_Tp, _Tp, _Tp>
    > {
    > _Tp
    > operator()(const _Tp& __x, const _Tp& __y) const
    > {
    > return _Tp(__x ^ __y);
    > }
    > };
    >
    > as mentionned in another email the specification transform
    > allow output to be the same iterator as input2.
    >
    > But I still wonder whether / how could I make use of the biwise and
    > assignement in one operator a ^= b instead of a = a ^ b?


    What about this:

    //---------------------------------
    // apply a BinOp to each item of two ranges
    template<typename It1, typename It2, typename BinOp>
    BinOp for2(It1 f1, It1 l1, It2 f2, BinOp bop)
    {
    for ( ; f1 != l1; ++f1, ++f2)
    bop(*f1, *f2);

    return bop;
    }

    // do __x ^= __y
    template <class _Tp>
    struct xor_assign : public std::binary_function<_Tp, _Tp, void>
    {
    void
    operator()(_Tp& __x, const _Tp& __y) const
    {
    __x ^= __y;
    }
    };

    string s1 = "ABCD";
    string s2 = "EFGH";

    for2(s1.begin(), s1.end(), s2.begin(), xor_assign<char>());
    //---------------------------------

    A quick test gave me a sensible result.

    HTH

    Stefan
    --
     
    Stefan =?UTF-8?B?TsOkd2U=?=, Nov 2, 2005
    #6
  7. Patrick Guio

    Patrick Guio Guest

    On Wed, 2 Nov 2005, Bob Hairgrove wrote:

    Hello Bob,



    > First of all, you should never use the names beginning with an
    > underscore because these are reserved for the library.
    >
    > Secondly, your class inherits from a concrete specialization of a
    > template class; it is not a template class!
    >
    > Thirdly, your function needs to return char (not bool), which is what
    > the vectors are declared to contain.


    Oops my fault, I did grab the template class (too quickly obviously) from
    logical_or in (||) <algorithm> which is not the bitwise or operator (|)

    I don't want to loose generality and it looks like it works well
    with the following definition

    template <class _Tp>
    struct logical_xor : public std::binary_function<_Tp, _Tp, _Tp>
    {
    _Tp
    operator()(const _Tp& __x, const _Tp& __y) const
    {
    return _Tp(__x ^ __y);
    }
    };

    as mentionned in another email the specification transform
    allow output to be the same iterator as input2.

    But I still wonder whether / how could I make use of the biwise and
    assignement in one operator a ^= b instead of a = a ^ b?

    Any idea?

    Sincerely,

    Patrick
     
    Patrick Guio, Nov 2, 2005
    #7
  8. On Wed, 02 Nov 2005 15:31:12 +0100, Stefan Näwe
    <stefan_NOSPAM@NOSPAM_naewe.de> wrote:

    >// do __x ^= __y
    >template <class _Tp>
    >struct xor_assign : public std::binary_function<_Tp, _Tp, void>
    >{
    > void
    > operator()(_Tp& __x, const _Tp& __y) const
    > {
    > __x ^= __y;
    > }
    >};


    You should never use names with leading underscores -- see 17.4.3.1.2
    of the standard.

    --
    Bob Hairgrove
     
    Bob Hairgrove, Nov 2, 2005
    #8
  9. Patrick Guio

    Guest

    Bob Hairgrove wrote:
    > On Wed, 02 Nov 2005 15:31:12 +0100, Stefan Näwe
    > <stefan_NOSPAM@NOSPAM_naewe.de> wrote:
    >
    > >// do __x ^= __y
    > >template <class _Tp>
    > >struct xor_assign : public std::binary_function<_Tp, _Tp, void>
    > >{
    > > void
    > > operator()(_Tp& __x, const _Tp& __y) const
    > > {
    > > __x ^= __y;
    > > }
    > >};

    >
    > You should never use names with leading underscores -- see 17.4.3.1.2
    > of the standard.


    Or names with double underscores anywhere in the name.

    Gavin Deane
     
    , Nov 2, 2005
    #9
  10. On 2005-11-02 08:46:46 -0500, Bob Hairgrove <> said:

    > On Wed, 02 Nov 2005 14:28:21 +0100, Stefan Näwe <>
    > wrote:
    >
    >> From '25.2.3 Transform [lib.alg.transform]':
    >>
    >> ...
    >> 5 Notes: result may be equal to first in case of unary transform, or to
    >> first1 or first2 in
    >> case of binary transform.

    >
    > Thanks for this. I'm glad to know that the standard allows it. I was
    > reading documentation from an older version of MSDN, which I shouldn't
    > have done...but I was too lazy to get my heavy standards book off the
    > shelf! Now I'll know better
    >
    > Here's what the MSDN for VS 6.0 says:
    >
    > "transform
    > template<class InIt, class OutIt, class Unop>
    > OutIt transform(InIt first, InIt last, OutIt x, Unop uop);
    > template<class InIt1, class InIt2, class OutIt, class Binop>
    > OutIt transform(InIt1 first1, InIt1 last1, InIt2 first2,
    > OutIt x, Binop bop);
    > The first template function evaluates *(x + N) = uop(*(first + N))
    > once for each N in the range [0, last - first). It then returns x +
    > (last - first). The call uop(*(first + N)) must not alter *(first +
    > N).
    >
    > The second template function evaluates *(x + N) = bop(*(first1 + N),
    > *(first2 + N)) once for each N in the range [0, last1 - first1). It
    > then returns x + (last1 - first1). The call bop(*(first1 + N),
    > *(first2 + N)) must not alter either *(first1 + N) or *(first2 + N)."
    > ^^^^^^^^^^^^^^
    >
    > I'm glad they have caught up with the standard here.


    You're misreading the MSDN documentation as well. That last sentence of
    each paragraph simply says that the _functor itself_ mustn't alter the
    values, not that std::transform won't do so.


    --
    Clark S. Cox, III
     
    Clark S. Cox III, Nov 2, 2005
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Steffen Brinkmann

    <algorithm> transform modification

    Steffen Brinkmann, Sep 21, 2003, in forum: C++
    Replies:
    20
    Views:
    785
    Steffen Brinkmann
    Sep 24, 2003
  2. Piotr

    STL transform algorithm

    Piotr, Feb 14, 2006, in forum: C++
    Replies:
    5
    Views:
    440
    Daniel T.
    Feb 14, 2006
  3. Diego Martins

    Transform algorithm 1-n, n-1 or m-n

    Diego Martins, Oct 18, 2006, in forum: C++
    Replies:
    2
    Views:
    293
    Fraser Ross
    Oct 19, 2006
  4. suresh
    Replies:
    2
    Views:
    322
    suresh
    Dec 30, 2007
  5. Gerald I. Evenden

    Problem with <algorithm> transform

    Gerald I. Evenden, Jan 6, 2008, in forum: C++
    Replies:
    13
    Views:
    551
    James Kanze
    Jan 8, 2008
Loading...

Share This Page