Important: This question becomes quite long, if you are reading this for the first time, I suggest you start from scratch, as the solution exists in a roundabout way, but the code is a little smelly.
After reading the template manual, I was able to modify an existing class to support generic types. However, many objects already depend on this, so I'm looking for a way to create a generic method, and not the entire class.
I tried the following, but it seems that this behavior is not supported.
// foobar1.h // Don't want the entire class to be generic. //template<class T> class FooBar1 { public: template<class T> T Foo(); } // foobar2.h class FooBar2 : public FooBar1 { } // foobar1.cpp template<class T> T FooBar1::Foo() { return something; } // test.cpp FooBar1 fb1; FooBar2 fb2 = fb1.Foo<FooBar2>();
Is this supposed to not work, or is it a bug elsewhere that I'm confused with?
undefined reference to FooBar2 Foo<FooBar2>()
To imagine this in some perspective regarding what I want to achieve, here is how I would do it in C # ...
pubic class FooBar1 { public T Foo<T>() where T : FooBar1 { return something; } } public class FooBar2 : FooBar1 { } FooBar1 fb1 = new FooBar1(); FooBar2 fb2 = fb1.Foo<FooBar2>();
Is there a way to do something like this in C ++?
Update 1:
Some minor syntax details have been fixed (I wanted to make Foo public and return T, not FooBar2). Still getting a compiler error ... When I remove the behavior of the template, the error disappears, the answer still says what I am doing is valid ... but if so, why am I still getting the error? Thank you for your responses!
Update 2:
Josh, this is real source code (well, what I find relevant, anwyay - let me know if you think I missed an important bit).
// ImageMatrix.h class ImageMatrix : public VImage { public: // ... various functions ... template<class T> T GetRotatedCopy(VDouble angle); } // ImageFilter.h class ImageFilter : public ImageMatrix { // ... various functions ... } // ImageMatrix.cpp template<class T> T ImageMatrix::GetRotatedCopy(VDouble angle) { // ... create a new instance of ImageMatrix and return it. } // ImageProcessor.cpp ImageFilter filter2 = filterPrototype.GetRotatedCopy<ImageFilter>(90);
And here is the real compiler error:
/home/nick/Projects/ViMRID/vimrid/Debug/libvimrid.so: undefined link to `vimrid :: imaging :: processing :: ImageFilter vimrid :: imaging :: ImageMatrix :: GetRotatedCopy (double) '
Update 3:
By the way, everything except the implementation string is in the library; therefore it is called from a separate binary file ... Does it matter? Correction; all this in the same library. All blocks are different files.
Update 4:
When I comment on the implementation line (ImageFilter filter2 = filterPrototype ...), it builds fine, so this line seems to call it ...
Update 5 (allowed?):
Still having problems ... Could this be a problem with namespaces? Scratch, that, OK, I understood the concept of templates now! :) The template definition should be in the header along with the ad (on the right?) - so now that I have moved the ad to ImageMatrix.h , everything will compile. However, I had to use dynamic_cast to make it work; it is right? If I leave, please correct me!
// This is in the header file! // Help!!! This looks really really smelly... template<class T> T ImageMatrix::GetRotatedCopy(VDouble angle) { ImageMatrix image = _getRotatedCopy(angle); ImageMatrix *imagePtr = ℑ return *dynamic_cast<T*>(imagePtr); }
Update 6:
Referring to update 5 when I do not use dynamic_cast ...
template<class T> T ImageMatrix::GetRotatedCopy(VDouble angle) { ImageMatrix image = _getRotatedCopy(angle); ImageMatrix *imagePtr = ℑ
... I get this error ...
../src/imaging/processing/../ImageMatrix.h: In member function 'T vimrid::imaging::ImageMatrix::GetRotatedCopy(vimrid::VDouble) [with T = vimrid::imaging::processing::ImageFilter]': ../src/imaging/processing/ImageProcessor.cpp:32: instantiated from here ../src/imaging/processing/../ImageMatrix.h:45: error: conversion from 'vimrid::imaging::ImageMatrix' to non-scalar type 'vimrid::imaging::processing::ImageFilter' requested make: *** [src/imaging/processing/ImageProcessor.o] Error 1
Update 7:
Also, if I donβt use all this smelly code in update 6 ...
class ImageMatrix : public VImage { public: template<class T> T GetRotatedCopy(VDouble angle); private: ImageMatrix _getRotatedCopy(VDouble angle); }; template<class T> T ImageMatrix::GetRotatedCopy(VDouble angle) { return _getRotatedCopy(angle); }
... I get the same error as in update 6.