vtkSmartPointer and vtkNew in VTK's API. Best practices?

Ah, I see. I can explain it a bit more if the prior discussion was too advanced. It’s not so much a purist issue as it is a practical safeguard against dangerous coding patterns that introduce subtle and difficult-to-spot bugs.

In a nutshell, allowing temporary RAII containers to implicitly provide access to their resources is a dangerous design, as the pointer obtained from the implicit cast will be released at the end of the line. It’s similar to the reason std::string won’t implicitly cast to const char*, for example:

std::string someFunction();

const char *timebomb = someFunction().c_str();

where timebomb is a pointer to freed memory.

There are two ways to fix your snippet with the proposed change, both are simple fixes:

  1. Explicitly Get() the pointer from the temporary (equivalent to calling c_str()). This says “I know there is a conversion here, and I’ve checked that it’s safe”.
Output->SetLines(vtkSmartPointer<vtkCellArray>::New().Get())
  1. Store the temporary in an named lvalue, and the implicit cast will still work:
auto lines = vtkSmartPointer<vtkCellArray>::New();
Output->SetLines(lines);

While these might seem contrived since SetLines does reference counting, disabling the implicit cast for rvalues prevents more subtly buggy code like

vtkSmartPointer<vtkCellArray> someFunction();

vtkCellArray *oops = someFunction();
oops->Register(); // crash; the vtkSmartPointer dtor freed
                  // the vtkCellArray in the previous line.

from compiling. Like the std::string example, the oops pointer references freed memory and will cause problems, possibly much later in execution and in a different context after getting passed around. But by disabling the implicit cast for rvalues, we get an immediate compile error at the buggy line, instead of a phantom segfault in a random spot later in the program at runtime.