[Insight-users] Template functions

Stuart Golodetz itk at gxstudios.net
Mon Nov 1 18:16:31 EDT 2010


On 01/11/2010 20:25, David Doria wrote:
> If I template a function on T and T is a itk::Image<unsigned
> char>::Pointer, all is well (as below):
>
> class Test
> {
>    public:
>    template<class T>
>    void Add(T patch);
> };
>
> template<class T>
> void Test::Add(T patch)
> {
>
> }
>
> int main(int, char*[])
> {
>    Test a;
>    itk::Image<unsigned char>::Pointer image;
>    a.Add(image);
>    return EXIT_SUCCESS;
> }
>
> However, if I template the function on T::Pointer where T is
> itk::Image<unsigned char>, I get errors. I even tried to explicitly
> instantiate the template:
>
> #include<itkImage.h>
>
> class Test
> {
>    public:
>    template<class T>
>    void Add(typename T::Pointer patch);
> };
>
> template<class T>
> void Test::Add(typename T::Pointer patch)
> {
>
> }
>
> template void Test::Add(itk::Image<unsigned char>::Pointer); // instantiate
>
> int main(int, char*[])
> {
>    Test a;
>    itk::Image<unsigned char>::Pointer image;
>    a.Add(image);
>    return EXIT_SUCCESS;
> }
>
> error: template-id ‘Add<>’ for ‘void
> Test::Add(itk::SmartPointer<itk::Image<unsigned char, 2u>  >)’ does not
> match any template declaration
> error: no matching function for call to
> ‘Test::Add(itk::SmartPointer<itk::Image<unsigned char, 2u>  >&)’
>
> I see that this is done all over ITK, but I can't figure out why it
> won't work here. Any ideas?
>
> Thanks,
>
> David

Off the top of my head, I think the phrase is "non-deducible context". 
When you call:

a.Add(image);

It knows that image is of type itk::Image<unsigned char>::Pointer, but 
it can't use that to deduce the image type (itk::Image<unsigned char>). 
The issue is that other classes could also contain a Pointer typedef 
which yields itk::SmartPointer<itk::Image<unsigned char> >, so the 
compiler can't deduce it.

To give a clearer example:

#include <iostream>

struct X
{
     typedef int value;
};

struct Y
{
     typedef int value;
};

template <typename T>
void f(typename T::value v)
{
     std::cout << v << '\n';
}

int main()
{
     //f(X::value(23));    // fails (could not deduce template argument)
     f<X>(X::value(23));    // succeeds
     return 0;
}

Cheers,
Stu


More information about the Insight-users mailing list