[iterator] Writable transform_iterator: how to?
Hello, I cannot figure out why the following code is wrong: #include <iostream> #include <vector> #include <functional> #include <boost/iterator/transform_iterator.hpp> struct f : public std::unary_function<int, int&> { int& operator()(int& x) { return x; } }; typedef std::vector<int> vec_type; typedef boost::transform_iterator<f, vec_type::iterator> trans_iter_type; int main() { vec_type V; V.push_back(4); trans_iter_type it(boost::make_transform_iterator(V.begin(), f())); std::cout << *it << std::endl; *it = 8; std::cout << *it << std::endl; return 0; } The compiler (g++ 4.0.1) complains about dereferencing and the error message says: error: passing ‘const f’ as ‘this’ argument of ‘int& f::operator()(int&)’ discards qualifiers Nicola
Does this work? struct f : public std::unary_function<int, int&> { int operator()(int& x) { return x; } }; -----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Nicola Sent: 11 April 2008 10:11 To: boost-users@lists.boost.org Subject: [Boost-users] [iterator] Writable transform_iterator: how to? Hello, I cannot figure out why the following code is wrong: #include <iostream> #include <vector> #include <functional> #include <boost/iterator/transform_iterator.hpp> struct f : public std::unary_function<int, int&> { int& operator()(int& x) { return x; } }; typedef std::vector<int> vec_type; typedef boost::transform_iterator<f, vec_type::iterator> trans_iter_type; int main() { vec_type V; V.push_back(4); trans_iter_type it(boost::make_transform_iterator(V.begin(), f())); std::cout << *it << std::endl; *it = 8; std::cout << *it << std::endl; return 0; } The compiler (g++ 4.0.1) complains about dereferencing and the error message says: error: passing ‘const f’ as ‘this’ argument of ‘int& f::operator()(int&)’ discards qualifiers Nicola ______________________________________________________________________ This email has been scanned by the MessageLabs Email Security System. For more information please visit http://www.messagelabs.com/email ______________________________________________________________________ ****************************************************************************** "This message and any attachments are solely for the intended recipient and may contain confidential and privileged information. If you are not the intended recipient, any disclosure, copying, use, or distribution of the information included in this message and any attachments is prohibited. If you have received this communication in error, please notify us by reply e-mail and immediately and permanently delete this message and any attachments. Thank you." Interactive Transaction Solutions Ltd (2473364 England) Registered Office: Systems House, Station Approach Emsworth PO10 7PW ********************************************************************** Ce message �lectronique contient des informations confidentielles � l'usage unique des destinataires indiqu�s, personnes physiques ou morales. Si vous n'�tes pas le destinataire voulu, toute divulgation, copie, ou diffusion ou toute autre utilisation de ces informations, est interdite. Si vous avez re�u ce message �lectronique par erreur, nous vous remercions d'en avertir son exp�diteur imm�diatement par email et de d�truire ce message ainsi que les �l�ments attach�s. Interactive transaction Solutions SAS- France (RCS Pontoise : 489 397 877) Si�ge social : Parc Saint Christophe, 10, Avenue de l�Entreprise 95865 Cergy-Pontoise Cedex ______________________________________________________________________ This email has been scanned by the MessageLabs Email Security System. For more information please visit http://www.messagelabs.com/email ______________________________________________________________________
In article <A194A82A1A084C4C8A29AD16E363B5F8FCDE36@WIN2003s325.its.local>, "Patrick Loney" <Patrick.Loney@InteractiveTS.com> wrote:
struct f : public std::unary_function<int, int&> { int operator()(int& x) { return x; } };
No, nor does struct f : public std::unary_function<int, int> { int operator()(int x) { return x; } }; or struct f { typedef int& result_type; result_type operator()(int& x) { return x; } }; The compiler complains upon dereferencing. But my goal is to be able to modify the iterator's value (i.e., to write *it = value), so the return type of the function object must be a reference. Maybe, I can use iterator_adaptor instead of transform_iterator? I have forgotten to mention that I am using Boost 1.34.1. Nicola
I've had to comment out the line //*it = 8; but the rest works under VC8 and increments the value in the vector: struct f : public std::unary_function<int, int> { int operator()(int x) const { return ++x; } }; typedef std::vector<int> vec_type; typedef boost::transform_iterator<f, vec_type::iterator> trans_iter_type; int _tmain(int argc, _TCHAR* argv[]) { vec_type V; V.push_back(4); trans_iter_type it(boost::make_transform_iterator(V.begin(),f())); std::cout << *it << std::endl; //*it = 8; std::cout << *it << std::endl; return 0; } -----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Nicola Sent: 11 April 2008 10:11 To: boost-users@lists.boost.org Subject: [Boost-users] [iterator] Writable transform_iterator: how to? Hello, I cannot figure out why the following code is wrong: #include <iostream> #include <vector> #include <functional> #include <boost/iterator/transform_iterator.hpp> struct f : public std::unary_function<int, int&> { int& operator()(int& x) { return x; } }; typedef std::vector<int> vec_type; typedef boost::transform_iterator<f, vec_type::iterator> trans_iter_type; int main() { vec_type V; V.push_back(4); trans_iter_type it(boost::make_transform_iterator(V.begin(), f())); std::cout << *it << std::endl; *it = 8; std::cout << *it << std::endl; return 0; } The compiler (g++ 4.0.1) complains about dereferencing and the error message says: error: passing ‘const f’ as ‘this’ argument of ‘int& f::operator()(int&)’ discards qualifiers Nicola ______________________________________________________________________ This email has been scanned by the MessageLabs Email Security System. For more information please visit http://www.messagelabs.com/email ______________________________________________________________________ ****************************************************************************** "This message and any attachments are solely for the intended recipient and may contain confidential and privileged information. If you are not the intended recipient, any disclosure, copying, use, or distribution of the information included in this message and any attachments is prohibited. If you have received this communication in error, please notify us by reply e-mail and immediately and permanently delete this message and any attachments. Thank you." Interactive Transaction Solutions Ltd (2473364 England) Registered Office: Systems House, Station Approach Emsworth PO10 7PW ********************************************************************** Ce message �lectronique contient des informations confidentielles � l'usage unique des destinataires indiqu�s, personnes physiques ou morales. Si vous n'�tes pas le destinataire voulu, toute divulgation, copie, ou diffusion ou toute autre utilisation de ces informations, est interdite. Si vous avez re�u ce message �lectronique par erreur, nous vous remercions d'en avertir son exp�diteur imm�diatement par email et de d�truire ce message ainsi que les �l�ments attach�s. Interactive transaction Solutions SAS- France (RCS Pontoise : 489 397 877) Si�ge social : Parc Saint Christophe, 10, Avenue de l�Entreprise 95865 Cergy-Pontoise Cedex ______________________________________________________________________ This email has been scanned by the MessageLabs Email Security System. For more information please visit http://www.messagelabs.com/email ______________________________________________________________________
In article <A194A82A1A084C4C8A29AD16E363B5F80100F620@WIN2003s325.its.local>, "Patrick Loney" <Patrick.Loney@InteractiveTS.com> wrote:
I've had to comment out the line //*it = 8; but the rest works under VC8 and increments the value in the vector:
struct f : public std::unary_function<int, int> { int operator()(int x) const { return ++x; } };
typedef std::vector<int> vec_type; typedef boost::transform_iterator<f, vec_type::iterator> trans_iter_type;
int _tmain(int argc, _TCHAR* argv[]) { vec_type V; V.push_back(4); trans_iter_type it(boost::make_transform_iterator(V.begin(),f())); std::cout << *it << std::endl; //*it = 8; std::cout << *it << std::endl; return 0; }
The above works for me as well. Adding the const qualifier has also solved my original problem. So, operator() must be const qualified. Is that documented somewhere or is it somehow inferrable? Thank you, Nicola
The above works for me as well. Adding the const qualifier has also solved my original problem. So, operator() must be const qualified. Is
that documented somewhere or is it somehow inferrable?
It's inferable - the error raised is with function: typename super_t::reference dereference() const { return m_f(*this->base()); } Which is const qualified (VS takes you to the function when you double click on the complier error, I expect your environment has a similar feature, if not change your environment...) ****************************************************************************** "This message and any attachments are solely for the intended recipient and may contain confidential and privileged information. If you are not the intended recipient, any disclosure, copying, use, or distribution of the information included in this message and any attachments is prohibited. If you have received this communication in error, please notify us by reply e-mail and immediately and permanently delete this message and any attachments. Thank you." Interactive Transaction Solutions Ltd (2473364 England) Registered Office: Systems House, Station Approach Emsworth PO10 7PW ********************************************************************** Ce message �lectronique contient des informations confidentielles � l'usage unique des destinataires indiqu�s, personnes physiques ou morales. Si vous n'�tes pas le destinataire voulu, toute divulgation, copie, ou diffusion ou toute autre utilisation de ces informations, est interdite. Si vous avez re�u ce message �lectronique par erreur, nous vous remercions d'en avertir son exp�diteur imm�diatement par email et de d�truire ce message ainsi que les �l�ments attach�s. Interactive transaction Solutions SAS- France (RCS Pontoise : 489 397 877) Si�ge social : Parc Saint Christophe, 10, Avenue de l�Entreprise 95865 Cergy-Pontoise Cedex ______________________________________________________________________ This email has been scanned by the MessageLabs Email Security System. For more information please visit http://www.messagelabs.com/email ______________________________________________________________________
In article <A194A82A1A084C4C8A29AD16E363B5F80100F635@WIN2003s325.its.local>, "Patrick Loney" <Patrick.Loney@InteractiveTS.com> wrote:
The above works for me as well. Adding the const qualifier has also solved my original problem. So, operator() must be const qualified. Is
that documented somewhere or is it somehow inferrable?
It's inferable - the error raised is with function:
typename super_t::reference dereference() const { return m_f(*this->base()); }
Which is const qualified
Ok, I see. Now, my problem is not yet solved, actually: *it is not a "valid lvalue". How can I make an assignment like *it = 8 valid? The documentation says that "the resulting transform_iterator models [...] Writable Lvalue Iterator if transform_iterator::reference is a non-const reference". Apparently, I am not able to achieve that in my sample code. Nicola
In article <nvitacolonna-B43572.13255311042008@ger.gmane.org>, Nicola <nvitacolonna@gmail.com> wrote:
Now, my problem is not yet solved, actually: *it is not a "valid lvalue". How can I make an assignment like *it = 8 valid?
Sorry, please ignore this. Adding 'const' will indeed do it. Nicola
participants (2)
-
Nicola
-
Patrick Loney