[container] Initialization from transformed_range compilation error
Hi,
snipped below gives this error in VS 2008 SP1:
Error 1 error C2664: 'void
boost::container::vector<T>::priv_range_insert<InIt>(Object
**,FwdIt,FwdIt,std::forward_iterator_tag)' : cannot convert parameter
4 from 'boost::detail::iterator_category_with_traversal
(adaptors::transform(ids, DecodeID())); }
Am I missing something obvious here?
Regards,
Szymon
P.S. full build log:
1>------ Build started: Project: copy_range, Configuration: Debug Win32 ------
1>Compiling...
1>main.cpp
1>c:\devel\boost_1_47_0\boost\container\vector.hpp(1908) : error
C2664: 'void boost::container::vector<T>::priv_range_insert<InIt>(Object
**,FwdIt,FwdIt,std::forward_iterator_tag)' : cannot convert parameter
4 from 'boost::detail::iterator_category_with_traversal
El 04/09/2011 12:12, Szymon Gatner escribió:
Hi,
snipped below gives this error in VS 2008 SP1:
Error 1 error C2664: 'void boost::container::vector<T>::priv_range_insert<InIt>(Object **,FwdIt,FwdIt,std::forward_iterator_tag)' : cannot convert parameter 4 from 'boost::detail::iterator_category_with_traversal
' to 'std::forward_iterator_tag' c:\devel\boost_1_47_0\boost\container\vector.hpp 1908 copy_range
AFAIK, Boost.Range does not support Boost.Container. Ion
2011/9/4 Ion Gaztañaga
El 04/09/2011 12:12, Szymon Gatner escribió:
Hi,
snipped below gives this error in VS 2008 SP1:
Error 1 error C2664: 'void boost::container::vector<T>::priv_range_insert<InIt>(Object **,FwdIt,FwdIt,std::forward_iterator_tag)' : cannot convert parameter 4 from 'boost::detail::iterator_category_with_traversal
' to 'std::forward_iterator_tag' c:\devel\boost_1_47_0\boost\container\vector.hpp 1908 copy_range AFAIK, Boost.Range does not support Boost.Container.
It is not something that Boost.Range should support explicitly imho as there is no problem with exact same code with std::vector instead of boost::container::vector. This is what copy_range does: template< typename SeqT, typename Range > inline SeqT copy_range( const Range& r ) { return SeqT( boost::begin( r ), boost::end( r ) ); } Code I attached just tries to initialize boost::container::vector from 2 iterators. (Same error when using explicit assign() method). Also copying transformed_range to a container::vector is OK, only (re) initialization fails. Regards, Simon -- Szymon Gatner The Lordz Games Studio www.thelordzgamesstudio.com
El 04/09/2011 23:08, Szymon Gatner escribió:
2011/9/4 Ion Gaztañaga
: El 04/09/2011 12:12, Szymon Gatner escribió:
Hi,
snipped below gives this error in VS 2008 SP1:
Error 1 error C2664: 'void boost::container::vector<T>::priv_range_insert<InIt>(Object **,FwdIt,FwdIt,std::forward_iterator_tag)' : cannot convert parameter 4 from 'boost::detail::iterator_category_with_traversal
' to 'std::forward_iterator_tag' c:\devel\boost_1_47_0\boost\container\vector.hpp 1908 copy_range AFAIK, Boost.Range does not support Boost.Container.
It is not something that Boost.Range should support explicitly imho as there is no problem with exact same code with std::vector instead of boost::container::vector.
Ok, I'll try to check what's wrong with Boost.Container. Thanks for the report Ion
2011/9/5 Ion Gaztañaga
Ok, I'll try to check what's wrong with Boost.Container.
Thanks for the report
I don't know if this is related but some of your insertion functions
have problems with implicit conversions. This fails:
#include
El 06/09/2011 1:17, Daniel James escribió:
2011/9/5 Ion Gaztañaga
: Ok, I'll try to check what's wrong with Boost.Container.
Thanks for the report
I don't know if this is related but some of your insertion functions have problems with implicit conversions. This fails:
#include
#include<string> int main() { boost::container::vectorstd::string x; x.push_back("something"); }
I think you possibly should use is_convertible for your SFINAE functions rather than is_same, so that they're instantiated for anything that has an implicit conversion to your argument. We discussed this recently:
it's a bit more complicated than that, there was no overload for non-class convertible types to class in the insertion macro. I'll fix this ASAP. Ion
El 06/09/2011 1:17, Daniel James escribió:
2011/9/5 Ion Gaztañaga
: Ok, I'll try to check what's wrong with Boost.Container.
Thanks for the report
I don't know if this is related but some of your insertion functions have problems with implicit conversions. This fails:
I think I've corrected this. Can you try trunk (boost.move+boost.container) code please? Ion
2011/9/6 Ion Gaztañaga
El 06/09/2011 1:17, Daniel James escribió:
2011/9/5 Ion Gaztañaga
: Ok, I'll try to check what's wrong with Boost.Container.
Thanks for the report
I don't know if this is related but some of your insertion functions have problems with implicit conversions. This fails:
I think I've corrected this. Can you try trunk (boost.move+boost.container) code please?
That fixed it, but I found another failure:
#include
El 07/09/2011 1:31, Daniel James escribió:
#include
#include<string> struct template_symbol { boost::container::vectorstd::string params; };
int main() { boost::container::vector
storage; template_symbol symbol; storage.push_back(symbol); }
That's a limitation of the move emulation explained in the documentation:
The macro BOOST_COPYABLE_AND_MOVABLE needs to define a copy constructor
for copyable_and_movable taking a non-const parameter in C++03 compilers:
//Generated by BOOST_COPYABLE_AND_MOVABLE
copyable_and_movable &operator=(copyable_and_movable&){/**/}
Since the non-const overload of the copy constructor is generated,
compiler-generated assignment operators for classes containing
copyable_and_movable will get the non-const copy constructor overload,
which will surely surprise users:
class holder
{
copyable_and_movable c;
};
void func(const holder& h)
{
holder copy_h(h); //<--- ERROR: can't convert 'const holder&' to
'holder&'
//Compiler-generated copy constructor is non-const:
// holder& operator(holder &)
//!!!
}
This limitation forces the user to define a const version of the copy
assignment, in all classes holding copyable and movable classes which
might annoying in some cases.
If you define the copy constructor you avoid the error. Annoying, but
I've not found any workaround. AFter adding such operations, this works.
#include
2011/9/7 Ion Gaztañaga
That's a limitation of the move emulation explained in the documentation:
The macro BOOST_COPYABLE_AND_MOVABLE needs to define a copy constructor for copyable_and_movable taking a non-const parameter in C++03 compilers:
Seems to only be the case for the assignment operator, not the copy constructor. I added an assignment operator to the real code and now everything works fine. I noticed that you have a macro BOOST_COPYABLE_AND_MOVABLE_ALT which doesn't define the assignment operator, is that a way to avoid this problem? I'd be tempted to do that, implicit move assignment doesn't seem that important to me. While I'm here, can you add both libraries to libs/libraries.htm, libs/maintainers.txt, doc/src/boost.xml (unless you want the documentation to be built separately?) and add index files to the libraries' directories. Let me know if you need any help.
El 07/09/2011 22:30, Daniel James escribió:
2011/9/7 Ion Gaztañaga
: That's a limitation of the move emulation explained in the documentation:
The macro BOOST_COPYABLE_AND_MOVABLE needs to define a copy constructor for copyable_and_movable taking a non-const parameter in C++03 compilers:
Seems to only be the case for the assignment operator, not the copy constructor. I added an assignment operator to the real code and now everything works fine.
Yes, sorry, you are right.
I noticed that you have a macro BOOST_COPYABLE_AND_MOVABLE_ALT which doesn't define the assignment operator, is that a way to avoid this problem? I'd be tempted to do that, implicit move assignment doesn't seem that important to me.
The problem is that containers already define the non-const assignment operator, so there is nothing you can do with this, unless, I put a compile time switch to change move emulation in Boost.Container.
While I'm here, can you add both libraries to libs/libraries.htm, libs/maintainers.txt, doc/src/boost.xml (unless you want the documentation to be built separately?) and add index files to the libraries' directories. Let me know if you need any help.
I'll try to do it, I'll ping you if I found any problem, thanks, Ion
2011/9/7 Ion Gaztañaga
El 07/09/2011 22:30, Daniel James escribió:
I noticed that you have a macro BOOST_COPYABLE_AND_MOVABLE_ALT which doesn't define the assignment operator, is that a way to avoid this problem? I'd be tempted to do that, implicit move assignment doesn't seem that important to me.
The problem is that containers already define the non-const assignment operator, so there is nothing you can do with this, unless, I put a compile time switch to change move emulation in Boost.Container.
Sorry I wasn't clear. I was asking if BOOST_COPYABLE_AND_MOVABLE_ALT is something I can use in my own code instead of BOOST_COPYABLE_AND_MOVABLE?
El 08/09/2011 0:07, Daniel James escribió:
2011/9/7 Ion Gaztañaga
: El 07/09/2011 22:30, Daniel James escribió:
I noticed that you have a macro BOOST_COPYABLE_AND_MOVABLE_ALT which doesn't define the assignment operator, is that a way to avoid this problem? I'd be tempted to do that, implicit move assignment doesn't seem that important to me.
The problem is that containers already define the non-const assignment operator, so there is nothing you can do with this, unless, I put a compile time switch to change move emulation in Boost.Container.
Sorry I wasn't clear. I was asking if BOOST_COPYABLE_AND_MOVABLE_ALT is something I can use in my own code instead of BOOST_COPYABLE_AND_MOVABLE?
BOOST_COPYABLE_AND_MOVABLE_ALT for C++0x compilers so it is a bit useless wouldn't be portable. I guess BOOST_COPYABLE_AND_MOVABLE_ALT was there since the review but I forgot to remove it. If there is interest I can define and document it as an alternative. Best, Ion
Sorry, I wrote it too fast:
BOOST_COPYABLE_AND_MOVABLE_ALT *is not defined* for C++0x compilers so...
-------- Mensaje original --------
Asunto: Re: [container] Initialization from transformed_range
compilation error
Fecha: Thu, 08 Sep 2011 08:08:18 +0200
De: Ion Gaztañaga
2011/9/7 Ion Gaztañaga
: El 07/09/2011 22:30, Daniel James escribió:
I noticed that you have a macro BOOST_COPYABLE_AND_MOVABLE_ALT which doesn't define the assignment operator, is that a way to avoid this problem? I'd be tempted to do that, implicit move assignment doesn't seem that important to me.
The problem is that containers already define the non-const assignment operator, so there is nothing you can do with this, unless, I put a compile time switch to change move emulation in Boost.Container.
Sorry I wasn't clear. I was asking if BOOST_COPYABLE_AND_MOVABLE_ALT is something I can use in my own code instead of BOOST_COPYABLE_AND_MOVABLE?
BOOST_COPYABLE_AND_MOVABLE_ALT for C++0x compilers so it is a bit useless wouldn't be portable. I guess BOOST_COPYABLE_AND_MOVABLE_ALT was there since the review but I forgot to remove it. If there is interest I can define and document it as an alternative. Best, Ion
2011/9/8 Ion Gaztañaga
I guess BOOST_COPYABLE_AND_MOVABLE_ALT was there since the review but I forgot to remove it. If there is interest I can define and document it as an alternative.
It probably isn't worth complicating things at this point.
Code I attached just tries to initialize boost::container::vector from 2 iterators. (Same error when using explicit assign() method). Also copying transformed_range to a container::vector is OK, only (re) initialization fails.
Thanks, I'll try to fix it ASAP. Best, Ion
El 04/09/2011 23:08, Szymon Gatner escribió:
Code I attached just tries to initialize boost::container::vector from 2 iterators. (Same error when using explicit assign() method). Also copying transformed_range to a container::vector is OK, only (re) initialization fails.
I think I've corrected this. Can you try trunk (boost.move+boost.container) code please? Ion
2011/9/6 Ion Gaztañaga
El 04/09/2011 23:08, Szymon Gatner escribió:
Code I attached just tries to initialize boost::container::vector from 2 iterators. (Same error when using explicit assign() method). Also copying transformed_range to a container::vector is OK, only (re) initialization fails.
I think I've corrected this. Can you try trunk (boost.move+boost.container) code please?
I am afraid it didn't work, still getting exact same error. Does my code compile for you after those fixes? Regards, Simon
El 06/09/2011 22:22, Szymon Gatner escribió:
2011/9/6 Ion Gaztañaga
: El 04/09/2011 23:08, Szymon Gatner escribió:
Code I attached just tries to initialize boost::container::vector from 2 iterators. (Same error when using explicit assign() method). Also copying transformed_range to a container::vector is OK, only (re) initialization fails.
I think I've corrected this. Can you try trunk (boost.move+boost.container) code please?
I am afraid it didn't work, still getting exact same error. Does my code compile for you after those fixes?
Yes. Have you updated Boost.Move and Boost.Container to the latest version? Ion
2011/9/6 Ion Gaztañaga
Yes. Have you updated Boost.Move and Boost.Container to the latest version?
I checked twice to make sure I updated properly before replying last time but it seems it was not enough ;) It works properly now of course. Sorry for confusion and thanks for the quick fix. On a related note: what is the correct way to return named boost::container from a function in non-rvalue reference compiler (VS 2008 SP1) to make sure moving will be used instead of copying? My guess is that explicit move() call is needed to perform a conversion to rv object but maybe boost.move somehow detects movability on its own? Docs are not clear on that matter - only example I found returns a temporary: file_descriptor create_file_descriptor(const char *filename) { return file_descriptor(filename); } I mean: vector<int> makeNumbers() { vector<int> ret; // fills ret; return boost::move(ret) // <---------- or just: return ret; ? } Regards, Simon
El 07/09/2011 0:05, Szymon Gatner escribió:
It's moved, this feature produces the limitation (must define
copy-constructor for copyable types owning copyable and movables classes
like boost::container::vector) that Daniel has suffered. Example:
#include
2011/9/7 Ion Gaztañaga
El 07/09/2011 0:05, Szymon Gatner escribió:
It's moved, this feature produces the limitation (must define copy-constructor for copyable types owning copyable and movables classes like boost::container::vector) that Daniel has suffered. Example:
It is still not clear to me. What is moved and in under what conditions? Let me clarify me question: will this move or copy: boost::container::vector<int> makeInts() { boost::container::vector<int> ret; //.... return ret; } boost::container::vector<int> ints; ints = makeInts() <========= move or copy? Regards, Simon
El 07/09/2011 17:40, Szymon Gatner escribió:
2011/9/7 Ion Gaztañaga
: El 07/09/2011 0:05, Szymon Gatner escribió:
It's moved, this feature produces the limitation (must define copy-constructor for copyable types owning copyable and movables classes like boost::container::vector) that Daniel has suffered. Example:
It is still not clear to me. What is moved and in under what conditions?
Let me clarify me question: will this move or copy:
boost::container::vector<int> makeInts() { boost::container::vector<int> ret; //.... return ret; }
boost::container::vector<int> ints;
ints = makeInts()<========= move or copy?
Depending on the compiler, move or copy (Named return value optimization is not so friendly with emulated move semantics). If you want to be really sure, use return ::boost:move(ret); Best, Ion
participants (3)
-
Daniel James
-
Ion Gaztañaga
-
Szymon Gatner