[Insight-developers] Advice needed from C++ Template wizards.

Gaëtan Lehmann gaetan.lehmann at jouy.inra.fr
Tue Oct 26 15:40:02 EDT 2010


I'm not sure it can help in that case, but I've recently used a simple  
overloading of a templated method in ShapeLabelMapFilter.
I didn't see any breakage related to that code up to now...

   // it seems impossible to specialize a method without specializing  
the whole class, but we
   // can use simple overloading
   template<class TMapIntercept, class TSpacing> double  
PerimeterFromInterceptCount( TMapIntercept & intercepts, const  
TSpacing & spacing );
   double PerimeterFromInterceptCount( MapIntercept2Type & intercepts,  
const Spacing2Type spacing );
   double PerimeterFromInterceptCount( MapIntercept3Type & intercepts,  
const Spacing3Type spacing );

Here the first method works for any dimension, and the others for the  
2D and 3D cases, to implement a higher quality algorithm available for  
those two cases.
The templated method is used only if the image dimension is not 2 or 3.


For that particular bug, I think you should always cast: I've modified  
the CastImageFilter some time ago to make sure that it does something  
only if needed. If the input and the output are of the same type and  
the cast filter is run in place, then it simply do nothing.

Gaëtan



Le 26 oct. 10 à 21:04, Tom Vercauteren a écrit :

> Hi Kent,
>
> IIRC, the way I usually do that is, as proposed by Brad, to rely on
> the is_same type trait:
> http://www.boost.org/doc/libs/1_44_0/libs/type_traits/doc/html/boost_typetraits/reference/is_same.html
>
> To avoid fully qualifying the class, you should be able to do this:
>
> template <class TImageType, class TFeatureImageType>
> void AssignCannyInput(typename TFeatureImageType::Pointer &input,
> const boost::false_type &)
> {
>  m_Caster->SetInput(input);
>  m_Canny->SetInput(m_Caster->GetOutput());
> }
>
> template <class TImageType, class TFeatureImageType>
> void AssignCannyInput(typename TFeatureImageType::Pointer &input,
> const boost::true_type &)
> {
>  m_Canny->SetInput(input);
> }
>
> And then call it as
>
>  this->AssignCannyInput( input,
> boost::is_same<TImageType,TFeatureImageType>() );
>
> The compiler should be smart enough not to try and instantiate the
> "true_type" function when the types are different.
>
> Since you will not be able to rely on boost for ITK, you could
> reimplement this type trait in ITK or pull them from the std namespace
> if c++0x is available:
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2947.html
>
> Hope this helps,
> Tom
>
> On Tue, Oct 26, 2010 at 20:09, kent williams
> <norman-k-williams at uiowa.edu> wrote:
>> The problem — even allowing for partial specialization, runs into  
>> problems
>> of specializing template member functions in template classes —  
>> according to
>> what I’ve been able to read, you have to fully qualify the class  
>> before you
>> can specialize the template member function.
>>
>> I’m just going to go caveman on the problem and use  
>> reinterpret_cast.  It’s
>> one case where we know for certain that it won’t be a problem since  
>> the
>> typeid is tested before SetInput is called.  The reinterpret_cast  
>> will have
>> bogus results only in the case where the call is unreachable at  
>> runtime.
>>
>>
>> On 10/26/10 12:16 PM, "Bradley Lowekamp" <blowekamp at mail.nih.gov>  
>> wrote:
>>
>> Hello Kent,
>>
>> This is a lot easier now that we can use partial template  
>> specialization.
>> This reminds me of the common IsSameType construct (which you tried
>> something very similar with a function):
>>
>>  /// generic programming to test if T is the same type as U
>>     template <typename T, typename U>
>>     struct IsSameType {
>>       /// true if T is the same type as U
>>       static const bool result = false;
>>     };
>>
>>
>>     /// generic programming to test if T is the same type as U
>>     template <typename T>
>>     struct IsSameType<T,T> {
>>       /// true if T is the same type as U
>>       static const bool result = true;
>>     };
>>
>>
>> One way to address this is to define a class in the member function  
>> or as a
>> member of class. I believe you can do the needed partial  
>> specialization in
>> both of these scopes. Then just add a member function to the above  
>> construct
>> that is specific to that specialization.
>>
>> This is what I would try... not 100% it'll work though.
>>
>> Good luck,
>> Brad
>>
>> On Oct 26, 2010, at 12:36 PM, kent williams wrote:
>>
>> I'm trying to fix this bug:
>> http://public.kitware.com/Bug/view.php?id=3610
>>
>> the problem is this code:
>>
>>   typename TFeatureImageType::Pointer tempFeature;
>>   if ( typeid(TImageType) == typeid(TFeatureImageType))
>>     {
>>     m_Canny->SetInput(tempFeature);
>>     }
>>   else
>>     {
>>     m_Caster->SetInput(tempFeature);
>>     m_Canny->SetInput(m_Caster->GetOutput());
>>     }
>>
>> This code breaks if typeid(TImageType) !=  
>> typeid(TFeatureImageType), since
>> the compiler still compiles the top branch of the if statement, and  
>> the
>> m_Canny->SetInput() call will be in error because of incorrect  
>> parameter
>> type.
>>
>> I thought I could fix this with specialization, like this:
>>
>> // IN CLASS DEFINITION
>> template <class _TImageType, class _TFeatureImageType>
>> void AssignCannyInput(typename _TFeatureImageType::Pointer &input)
>> {
>>   m_Caster->SetInput(input);
>>   m_Canny->SetInput(m_Caster->GetOutput());
>> }
>> template <>
>> void AssignCannyInput<TImageType,TImageType>(typename  
>> TImageType::Pointer
>> &input)
>> {
>>   m_Canny->SetInput(input);
>> }
>>
>> But the compiler objects to the specialization inside the class  
>> definition,
>> and moving the specialization out of the class like this:
>>
>> // Removed from class definition, moved to TXX file
>> template< class TImageType, class TFeatureImageType >
>> template <>
>> void
>> CannySegmentationLevelSetFunction< TImageType, TFeatureImageType >
>> ::AssignCannyInput<TImageType,TImageType>
>> (typename TImageType::Pointer &input)
>> {
>>   m_Canny->SetInput(input);
>> }
>>
>> Is illegal as well.
>>
>> Does anyone know of a good Template MetaProgramming solution to  
>> this issue?
>> <ATT00001..txt>
>>
>> ========================================================
>>
>> Bradley Lowekamp
>>
>> Lockheed Martin Contractor for
>>
>> Office of High Performance Computing and Communications
>>
>> National Library of Medicine
>>
>> blowekamp at mail.nih.gov
>>
>>
>>
>>
>> _______________________________________________
>> Powered by www.kitware.com
>>
>> Visit other Kitware open-source projects at
>> http://www.kitware.com/opensource/opensource.html
>>
>> Kitware offers ITK Training Courses, for more information visit:
>> http://kitware.com/products/protraining.html
>>
>> Please keep messages on-topic and check the ITK FAQ at:
>> http://www.itk.org/Wiki/ITK_FAQ
>>
>> Follow this link to subscribe/unsubscribe:
>> http://www.itk.org/mailman/listinfo/insight-developers
>>
>>
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Kitware offers ITK Training Courses, for more information visit:
> http://kitware.com/products/protraining.html
>
> Please keep messages on-topic and check the ITK FAQ at:
> http://www.itk.org/Wiki/ITK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.itk.org/mailman/listinfo/insight-developers

-- 
Gaëtan Lehmann
Biologie du Développement et de la Reproduction
INRA de Jouy-en-Josas (France)
tel: +33 1 34 65 29 66    fax: 01 34 65 29 09
http://voxel.jouy.inra.fr  http://www.itk.org
http://www.mandriva.org  http://www.bepo.fr

-------------- next part --------------
A non-text attachment was scrubbed...
Name: PGP.sig
Type: application/pgp-signature
Size: 203 bytes
Desc: Ceci est une signature ?lectronique PGP
URL: <http://www.itk.org/mailman/private/insight-developers/attachments/20101026/8dae6a7b/attachment.pgp>


More information about the Insight-developers mailing list