1

I'm trying to use the function:

bool pcl::visualization::PCLVisualizer::addPointCloud(const pcl::PointCloud<pcl::PointXYZ >::ConstPtr & cloud,
const std::string &     id = "cloud",
int     viewport = 0     
)

So I have the following code as global variables:

pcl::PointCloud<pcl::PointXYZ> linaccpc;
const pcl::PointCloud<pcl::PointXYZ> * linptr = &linaccpc;
boost::shared_ptr<pcl::visualization::PCLVisualizer> linplotter (new pcl::visualization::PCLVisualizer("linear acceleration");

And then in my main function:

linplotter->addPointCloud<pcl::PointXYZ> (linptr, "linear acc", 0);

And I get the error:

error: no matching function for call to 'pcl::visualization::PCLVisualizer::addPointCloud(const pcl::PointCloud<pcl::PointXYZ>*&, const char [11], int)'
linplotter->addPointCloud<pcl::PointXYZ> (linptr, "linear acc", 0);
                                                                 ^

Any help is much appreciated.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
ksivakumar
  • 481
  • 2
  • 5
  • 19
  • read this http://stackoverflow.com/questions/57483/what-are-the-differences-between-a-pointer-variable-and-a-reference-variable-in – PiotrNycz Aug 26 '15 at 20:18
  • Is too hard to make a minimal example? – gsamaras Aug 26 '15 at 20:19
  • http://pointclouds.org/documentation/tutorials/pcl_visualizer.php I've been using this to help me. I also tried declaring the pointer as `pcl::PointCloud::ConstPtr linptr = linaccpc;` but getting an error with conversion from 'pcl::PointCloud' to non-scalar type 'pcl::PointCloud::ConstPtr {aka boost::shared_ptr >}' requested – ksivakumar Aug 26 '15 at 20:20
  • 2
    Thanks KS, however this thing requires boost, which I am not in a mood to download now. I mean that you could make a minimal example with the same case of const pointers. That way it would be super easy to help you, at least in my case. :) – gsamaras Aug 26 '15 at 20:22
  • @gsamaras If you have a C++11 compiler you may use `std::shared_ptr` which is very similar to what `boost::shared_ptr` was – M.M Aug 26 '15 at 21:19
  • @MattMcNabb: That assumes PCL will accept `std::shared_ptr` and not rely solely on `boost::shared_ptr` only. – Remy Lebeau Aug 26 '15 at 21:28
  • @MattMcNabb yes, but I am not the one seeking for help here. I really feel that a minimal example would be sweet here. But Remy felt generous. – gsamaras Aug 26 '15 at 21:38

1 Answers1

5

Look at the definition of addPointCloud() more carefully:

bool pcl::visualization::PCLVisualizer::addPointCloud(
    const pcl::PointCloud<pcl::PointXYZ >::ConstPtr & cloud,
    const std::string &     id = "cloud",
    int     viewport = 0     
)

Its first parameter is a const reference to a pcl::PointCloud<pcl::PointXYZ>::ConstPtr, where ConstPtr is a typedef for boost::shared_ptr<const PointCloud<pcl::PointXYZ>>.

You are trying to pass a pcl::PointCloud<pcl::PointXYZ>* where a boost::shared_ptr<const PointCloud<pcl::PointXYZ>> is expected. That does not match the definition.

boost::shared_ptr has an explicit constructor for single-value input, so the compiler cannot implicitly create a temporary boost::shared_ptr<const PointCloud<pcl::PointXYZ>> for your pcl::PointCloud<pcl::PointXYZ>* value.

To get around that, you will have to invoke the explicit constructor directly:

pcl::PointCloud<pcl::PointXYZ> linaccpc;
const pcl::PointCloud<pcl::PointXYZ> *linptr = &linaccpc;
...
linplotter->addPointCloud<pcl::PointXYZ> (pcl::PointCloud<pcl::PointXYZ>::ConstPtr(linptr), "linear acc", 0);

Or:

pcl::PointCloud<pcl::PointXYZ> linaccpc;
pcl::PointCloud<pcl::PointXYZ>::ConstPtr linptr (&linaccpc);
...
linplotter->addPointCloud<pcl::PointXYZ> (linptr, "linear acc", 0);

Note, however, that this will likely crash your code. By default, shared_ptr calls delete on any pointer you give it, so it will be calling delete on a memory address it has no business freeing. So allocate the pointer using new instead:

pcl::PointCloud<pcl::PointXYZ>::ConstPtr linptr (new pcl::PointCloud<pcl::PointXYZ>);
...
linplotter->addPointCloud<pcl::PointXYZ> (linptr, "linear acc", 0);

If you want to get around that and a variable whose lifetime you control, but that shared_ptr simply holds a pointer to, you will have to provide a custom deleter that will not free the variable memory when the shared_ptr is done using the pointer:

template <class T>
static void DoNotFree(T*)
{
}

...

pcl::PointCloud<pcl::PointXYZ> linaccpc;
pcl::PointCloud<pcl::PointXYZ>::ConstPtr linptr (&linaccpc, &DoNotFree<pcl::PointCloud<pcl::PointXYZ>>);
...
linplotter->addPointCloud<pcl::PointXYZ> (linptr, "linear acc", 0);

This last approach will only work if linplotter does not need to keep using the linaccpc variable after it goes out of scope, such as if linplotter is destroyed before lineaccpc. This is not something you should rely on, though. The primary purpose of shared_ptr is to manage an object's lifetime for you, so let it do its job. Use new.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    `pcl::PointCloud::ConstPtr linptr (&linaccpc);` will not be correct because the `shared_ptr` destructor will try to `delete &linaccpc`. (You show the correct technique on the next code snippet but since OP is new to smart pointers I think it would be good to clearly say "don't do this", and also reiterate that he needs to get rid of `linaccpc` and only use the smart pointer `linptr`) – M.M Aug 26 '15 at 21:18
  • Re. your edit: `linaccpc` is a global variable in OP's code, not a stack variable. – M.M Aug 26 '15 at 21:30
  • @MattMcNabb: Stack or global, the same risk applies. But I have re-worded my answer. – Remy Lebeau Aug 26 '15 at 21:31
  • So if I allocate the pointer using new, how would I point that to linaccpc, which is my point cloud object? I tried `linptr = &linaccpc;` on the next line, and I get `error: 'linptr' does not name a type`. Thank you everyone for all your help! – ksivakumar Aug 27 '15 at 16:27
  • 1
    If you allocate a `PointCloud` using `new`, it is already its own variable in memory, you would not need a separate `lineaccpc variable at all, you would get rid of that variable from your code. Please see the examples I showed in my answer. – Remy Lebeau Aug 27 '15 at 17:17