[TypeErasure] efficiency problem
Hello! In following code TypeErasure creates two copies of s, while Boost.Any creates no copies at all. any x{ s{} }; any y{ std::move(x) }; any z; z = std::move(y); There is move constructor for type_erasure::any, but it does allocate memory and calls copy constructor for s. Why? And why there is no move assignment operator in type_erasure::any? Thanks. Full source: https://wandbox.org/permlink/iHs5a0bjzXsBtpwC
Am 23.03.2017 um 06:55 schrieb Mikhail Strelnikov via Boost-users:
Hello!
In following code TypeErasure creates two copies of s, while Boost.Any creates no copies at all.
any x{ s{} }; any y{ std::move(x) }; any z; z = std::move(y);
There is move constructor for type_erasure::any, but it does allocate memory and calls copy constructor for s. Why?
I am not really sure, but I investigated this over a year ago and I think the problem was either that no real move-constructor was implemented or the wrong constructor overload was taken. (I think, taking the wrong overload happened at least in some of my personal test-cases back then. The constructor with the "universal reference" [1] very often better matched the inputs than some of the overloads.)
And why there is no move assignment operator in type_erasure::any?
A pull-request to Boost.TypeErasure exists [2] which adds support for move-assignment. (I wrote this about a year ago and we have been using it successfully in production-code at our company for over half a year now.) However, this pull-request seems to have been overlooked by the author of Boost.TypeErasure. If you do not mind using a patched version of Boost.TypeErasure you could apply this pull-request to your local version of Boost and use that. Of course, I would prefer if this pull-request (or some other pull-request adding move-assignment support) would make it into the official version of Boost.TypeErasure. Hope that helps, Deniz [1] https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers [2] https://github.com/boostorg/type_erasure/pull/12
Thanks.
Full source: https://wandbox.org/permlink/iHs5a0bjzXsBtpwC _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
I had to change the declaration of my any to:
using any = boost::type_erasure::any
;
And then I've tried your patch, it works, thanks.
But it solves only half of the problem - there is still memory
allocation happening every time type_erasure::any is move-constructed
or move-assigned (again, there are no extra memory allocations in this
case when Boost.Any is used).
2017-03-23 15:10 GMT+03:00 Deniz Bahadir via Boost-users
Am 23.03.2017 um 06:55 schrieb Mikhail Strelnikov via Boost-users:
Hello!
In following code TypeErasure creates two copies of s, while Boost.Any creates no copies at all.
any x{ s{} }; any y{ std::move(x) }; any z; z = std::move(y);
There is move constructor for type_erasure::any, but it does allocate memory and calls copy constructor for s. Why?
I am not really sure, but I investigated this over a year ago and I think the problem was either that no real move-constructor was implemented or the wrong constructor overload was taken. (I think, taking the wrong overload happened at least in some of my personal test-cases back then. The constructor with the "universal reference" [1] very often better matched the inputs than some of the overloads.)
And why there is no move assignment operator in type_erasure::any?
A pull-request to Boost.TypeErasure exists [2] which adds support for move-assignment. (I wrote this about a year ago and we have been using it successfully in production-code at our company for over half a year now.) However, this pull-request seems to have been overlooked by the author of Boost.TypeErasure.
If you do not mind using a patched version of Boost.TypeErasure you could apply this pull-request to your local version of Boost and use that. Of course, I would prefer if this pull-request (or some other pull-request adding move-assignment support) would make it into the official version of Boost.TypeErasure.
Hope that helps, Deniz
[1] https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers [2] https://github.com/boostorg/type_erasure/pull/12
Thanks.
Full source: https://wandbox.org/permlink/iHs5a0bjzXsBtpwC _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
AMDG On 03/22/2017 11:55 PM, Mikhail Strelnikov via Boost-users wrote:
In following code TypeErasure creates two copies of s, while Boost.Any creates no copies at all.
any x{ s{} }; any y{ std::move(x) };
Boost.TypeErasure tries to be as faithful as possible to normal overload resolution rules. As a result, the move constructor should resolve as follows: If constructible
is present Allocate a new object and call the captured move constructor to initialize it. Else if constructible
is present Allocate a new object and initialize it with the copy constructor. Else Error If relaxed is present, then it would be possible to move the pointer, leaving the source any empty, but this isn't currently implemented.
any z; z = std::move(y);
There is move constructor for type_erasure::any, but it does allocate memory and calls copy constructor for s. Why?
And why there is no move assignment operator in type_erasure::any?
There will be once I get around to merging Deniz' PR. In Christ, Steven Watanabe
participants (3)
-
Deniz Bahadir
-
Mikhail Strelnikov
-
Steven Watanabe