# Template class already defined when using ITK TestDriver

**URL:** <https://discourse.itk.org/t/template-class-already-defined-when-using-itk-testdriver/3807>\
**Category:** Engineering\
**Created:** [January 29, 2021, 6:53am UTC](https://discourse.itk.org/t/template-class-already-defined-when-using-itk-testdriver/3807 "2021-01-29T06:53:28Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![LucasGandel](https://discourse.itk.org/user_avatar/discourse.itk.org/lucasgandel/32/1147_2.png) [@LucasGandel](https://discourse.itk.org/u/LucasGandel)\
**Post date:** [January 29, 2021, 6:53am UTC](https://discourse.itk.org/t/template-class-already-defined-when-using-itk-testdriver/3807/1 "2021-01-29T06:53:28Z")

</div>

We are facing redefinition issues when using the ITK TestDriver approach for testing the RTK remote module (following a previous discussion [here](https://discourse.itk.org/t/io-dlls-not-found/3464/5)).

When linking the TestDriver executable to the RTK test libs, the MSVC linker complains about template classes already being defined in the test .obj file.

itkRTK-5.2.lib(itkRTK-5.2.dll) : error LNK2005: “protected: virtual \_\_cdecl itk::InPlaceImageFilter\<class itk::CudaImage\<float,3\>,class itk::CudaImage\<float,3\> \>::~InPlaceImageFilter\<class itk::CudaImage\<float,3\>,class itk::CudaImage\<float,3\> \>(void)” (??1?$InPlaceImageFilter@V?$CudaImage@M$02@itk@@V12@@itk@@MEAA@XZ) already defined in rtkTemplateTest2.cxx.obj

The error only happens when RTK CUDA-related classes are included from a test, probably because most of those classes are inheriting from [explicit templates](https://github.com/SimonRit/RTK/blob/master/include/rtkCudaRayCastBackProjectionImageFilter.h#L49-L52).

A solution to the issue is to avoid explicit instantiation by using [templates for CUDA classes](https://github.com/SimonRit/RTK/blob/master/include/rtkCudaBackProjectionImageFilter.h#L49-L51) too, but the template would be constrained to one type only using concept checking.

We also looked into using extern template declarations for the base classes, similar to [ITKTransformIOBase](https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/IO/TransformBase/include/itkTransformIOBase.h#L226), but it does not seem adequate because it means explicit instantiation with CudaImage in files of a module independent of ITKCudaCommon (e.g., itkInPlaceImageFilter.h for the error above).

What would be the recommended way to handle this for ITK (remote) modules? Is it a known good practice to always template classes inheriting from templated classes?

We created a small [example](https://github.com/LucasGandel/RTK/blob/rtk-template/test/CMakeLists.txt)to reproduce the problem using 2 very simple tests.

Both tests are creating an instance of a subclass of itk::InPlaceImageFilter for itk::CudaImage\<float,3\>.

[Including RTK Cuda](https://github.com/LucasGandel/RTK/blob/rtk-template/test/rtkTemplateTest.cxx#L6) classes from one test throws the error reported above. What is not really clear is why including the same class in both tests works well.

Any suggestion would be much appreciated.

(Cc @simon.rit)

---

<div class="post-metadata">

**Author:** ![phcerdan](https://discourse.itk.org/user_avatar/discourse.itk.org/phcerdan/32/286_2.png) [@phcerdan](https://discourse.itk.org/u/phcerdan)\
**Post date:** [January 29, 2021, 9:05am UTC](https://discourse.itk.org/t/template-class-already-defined-when-using-itk-testdriver/3807/2 "2021-01-29T09:05:42Z")

</div>

Hi @LucasGandel,  
That is interesting. Do those examples compile as an independent external project (without using the CreateTestDriver mechanism)? Does it happen in other compiler other than MSVC?

With a class template, any “duplicated” instantiation is discarded at link time. But your filter is not a template (it’s a regular class that derive from explicit templates). I guess when you include the header, the compiler tries to instantiate those templates, but they are already defined in your lib. I wonder why they are not discarded.

My guess about why it fails when you include the header in one test but not in the other, is that the compiler uses the definition from your lib in the test without the header, and the generated instantiation in the test with the header, but when linking those in the test driver, it doesn’t know which one to discard.

I would try to create a MRE and ask in a C++ channel.

> **[Join the #include Discord Server!](https://discord.com/invite/ZPErMGW)**
>
> Check out the #include community on Discord - hang out with 5,457 other members and enjoy free voice and text chat.

> <https://stackoverflow.com/questions/33517902/how-to-export-a-class-derived-from-an-explicitly-instantiated-template-in-visual>

---

<div class="post-metadata">

**Author:** ![LucasGandel](https://discourse.itk.org/user_avatar/discourse.itk.org/lucasgandel/32/1147_2.png) [@LucasGandel](https://discourse.itk.org/u/LucasGandel)\
**Post date:** [January 29, 2021, 11:48am UTC](https://discourse.itk.org/t/template-class-already-defined-when-using-itk-testdriver/3807/3 "2021-01-29T11:48:58Z")

</div>

Hi @phcerdan,

Thank you for your answer!

Yes the examples work well when using a combination of add\_executable() and itk\_add\_test() (having one executable per test). And this is specific to MSVC, our understanding is that only gcc discard the duplicated instantiation.

Reproducing this with a small C++ example sounds like a good plan. I wanted to confirm whether this use case had already been solved in ITK. I’ll keep you posted here, thanks for providing good resources.

---

<div class="post-metadata">

**Author:** ![simon.rit](https://discourse.itk.org/letter_avatar_proxy/v4/letter/s/f08c70/32.png) [@simon.rit](https://discourse.itk.org/u/simon.rit)\
**Post date:** [April 14, 2026, 2:22pm UTC](https://discourse.itk.org/t/template-class-already-defined-when-using-itk-testdriver/3807/4 "2026-04-14T14:22:26Z")

</div>

For the record, if anyone faces a similar problem, we ended up using explicit instantiation to solve this

> <https://github.com/RTKConsortium/RTK/pull/900/commits/5c50b8293650f0c7591ecb266eff2cdbc5421216>
>
> The problem is caused by the explicit definition of templated parents
> in Cuda fi…lters. The parents are now explicitely instantiated to avoid
> this problem.
