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

Tom Vercauteren tom.vercauteren at m4x.org
Tue Oct 26 15:04:32 EDT 2010


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
>
>


More information about the Insight-developers mailing list