Why is const_cast used inside filters?

The ITK Software Guide (Book 1) has an example of a creating a composition filter. In the GenerateData method, a const_cast is used to cast a pointer to const data into a pointer to data. This is done for the input image.

template< typename TImage >
void
CompositeExampleImageFilter< TImage >
::GenerateData()
{
typename ImageType::Pointer input = ImageType::New();
input->Graft( const_cast< ImageType * >( this->GetInput() ));
m_GradientFilter->SetInput( input );
m_ThresholdFilter->ThresholdBelow( this->m_Threshold );
m_RescaleFilter->GraftOutput( this->GetOutput() );
m_RescaleFilter->Update();
this->GraftOutput( m_RescaleFilter->GetOutput() );
}

I never questioned it until a collaborator brought it up. Seeing const_cast seems like code smell. Why is this const_cast needed? Why is there no non-const access to internal data?

When I searched around, I found the following snippet from ImageRegistrationMethod:

template< typename TFixedImage, typename TMovingImage >
void
ImageRegistrationMethod< TFixedImage, TMovingImage >
::SetFixedImage(const FixedImageType *fixedImage)
{
  itkDebugMacro("setting Fixed Image to " << fixedImage);

  if ( this->m_FixedImage.GetPointer() != fixedImage )
{
this->m_FixedImage = fixedImage;

// Process object is not const-correct so the const_cast is required here
this->ProcessObject::SetNthInput( 0,
                                  const_cast< FixedImageType * >( fixedImage ) );

this->Modified();
}
}

The best explanation I can find is that ProcessObject was written many years ago. ProcessObject was not written const-correct. When the issue came up, instead of correcting ProcessObject to be const-correct and breaking a bunch of code, all derived classes from ProcessObject deal in const pointers to mediate the design.

Would this be a correct interpretation of why const_cast is used? Is there a better explanation?

1 Like

Hi Bryce,

The processing pipeline in its simplest form is

input ->[Filter]-> output

Conceptually, a filter should not be modifying its input. In practice for the exsting architecture, when the pipeline updates, the filter can modify the input’s RequestedRegion if, for example, its algorithm requires a larger RequestedRegion on the input to produce the RequestedRegion on the output.

HTH,
Matt

2 Likes