Migrate boost::function to std::function#3079
Migrate boost::function to std::function#3079SergioRAgostinho merged 12 commits intoPointCloudLibrary:masterfrom
boost::function to std::function#3079Conversation
|
I guess this can be counted as a "soft" API breakage. The changed types are either hidden behind typedefs or are compatible. In most cases the existing user code should still compile, right? |
This is the situation that I'm foreseeing to be a problem. User code of this type // make callback function from member function
boost::function<void (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr&)> f =
boost::bind (&SimpleOpenNIProcessor::cloud_cb_, this, _1);
// connect callback function for desired signal. In this case its a point cloud with color values
boost::signals2::connection c = interface->registerCallback (f);It will try to pass a |
|
One possibility for such situations is switch to using lambdas: auto f = [this](const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr& c){ this->cloud_cb_(c); };
boost::signals2::connection c = interface->registerCallback (f);This will compile with both 1.10 and earlier versions, however requires that C++11 is enabled even with old versions. |
You need to see from the consumer's perspective. Our users will still have in their codebases snippets like the one I mentioned above. What about setting these function argument types to |
Sure, this is understood. Ideally the users should not need to change anything. But if that is not possible, then the goal is at least to make it possible to modify the code such that it compiles with both old and new PCL without horrible
Not sure I understand. You mean making callback type it a template parameter? |
Now I understood the motifs behind your suggestion.
Sorry. My brain froze there for a second and I messed up keywords and their respective uses. A second templated type on these methods would be an option. Can we leverage overload resolution to deprecate just |
|
To be specific, let's talk about this method: pcl/io/include/pcl/io/grabber.h Lines 233 to 234 in f9fb3f5 C++ supports template template syntax, we can rewrite the aforementioned method as: template<typename T, template<typename> typename F> boost::signals2::connection
Grabber::registerCallback (const F<T> & callback) I've never used this C++ feature, so can not predict what implications this may have on compiler's abilities to resolve template arguments. I've tried to build the library with this single change and compilation succeeded, this much I can tell :) |
|
By the way, my first proposal with lambda does not work, the compiler is not able to deduct template argument because lambda is not derived from |
I suspect this won´t be enough. I feel that it's not capturing the variadic nature of function arguments. The typical function signature is defined like template< class R, class... Args >
class function<R(Args...)>;Nevertheless, try your proposed change on this PR just to see what happens. |
Well maybe, but |
If the users made use of the typedefs it should be ok 😅 (famous last words) I think we discussed this before. Preventing breakage would require some preprocessor conditionals to switch between boost/std and both agreed that those were ugly/terrible to keep around. So we keep it like this I guess. |
|
I wonder if it makes more sense to not split this conversion over multiple PRs. Right now the approach we took seems reasonable, but what if we hit some limitations further down the road? I've grepped through the code base, we have a little short of 300 matches for |
|
It's fine by me. I have a copy of each module on each separate branch but can merge everything into this one. Do you want me push all the commits at once or one commit at a time so we can monitor the CI at each step? |
9fc8749 to
8c217f6
Compare
|
Oh, I assumed that you haven't done the conversion for other modules yet. Did you try to build the entire thing locally? If it compiles fine, then push everything at once, hopefully will work on CI as well. |
I usually do it in a single go and then split every module into a separate branch. I only start these PRs once everything compiles on my environment.
Unfortunately I only build a subset of things due to the numerous 3rd parties :( I'll address your review comment and proceed as discussed. |
8c217f6 to
c94c2e6
Compare
|
I just skimmed quickly through some of the new commits and I'm already noticing that some of these commits have non trivial changes. :/ |
|
I'm still in the process of going through the commits. I noticed that now we have a lot of code like: std::function<...> cloud_cb = boost::bind (&..., this, _1);This compiles fine, but does not look nice. But I guess it's alright because we already have a pending PR that gets rid of |
Exactly! I will pick those up after this batch of function replacements. |
| */ | ||
| template<typename T> boost::signals2::connection | ||
| registerCallback (const boost::function<T>& callback); | ||
| registerCallback (const std::function<T>& callback); |
There was a problem hiding this comment.
Wasn't the idea to add FunctionT template parameter when we change boost to std in public API? Same way you did in the very first commit of this PR?
There was a problem hiding this comment.
I forgot about it. I'll go over it tomorrow.
|
Sounds right. |
494f5c6 to
75567d1
Compare
|
I just changed commits from d2986a3 (inclusive) onwards. Dropped 3 or 4 and added 2 at the end. Edit: I'll create the deprecation PR for the grabber callback registration once this one is merged. |
|
|
75567d1 to
ea0e78e
Compare
ea0e78e to
5f141b5
Compare
* Minor header reordering
* Add missing includes, reorganize headers.
* Add missing includes, reorganize headers.
* expose callback signature as a public type
* remove comments
5f141b5 to
57926b8
Compare
boost::function to std::function
This one requires some discussion. There's blatant API breakage, but I'm not really keen in keeping functions with signatures including boost types, around. I need more opinions on how to address this.