I've been working on a set of template classes that represent various bits of geometry, and I realized that I would like to be able to specialize various classes to handle references and pointers e.g.
template<typename T>
class rect{ // as in rectangle
public:
point<T> point1, point2; // Point simply contains two instances of type T
... // Twenty functions or so follow
};
template<typename T>
class rect<point<T>>{ // trying to put a point in a point makes no sense anyway
public: // so I see this technique as valid
point<T>& point1,& point2;
... // I really don't want to redefine them if I don't have to
};
The problems start with my test program
#include <iostream>
#include <TGeometry.hpp>
template<typename T>
class test{
public:
T A;
void myfunc(){std::cout << "from base\n";}
void otherfunc(T O);
test(const T nA) : A(nA) {}
test(){}
};
template<typename T>
void test<T>::otherfunc(T O){A += O;}
template<typename T>
class test<T&>{
public:
T& A;
void myfunc(){std::cout << "from refr\n";}
void otherfunc(T O); // Shouldn't this default to using test<T>::otherfunc?
test(T& nA) : A(nA) {}
};
int main(){ using std::cout;
using namespace d2;
test<int> Atest(5);
test<int&> Btest(Atest.A);
Atest.myfunc(), Btest.myfunc();
Btest.otherfunc(Atest.A); // test<T&>::otherfunc undefined?
Atest.otherfunc(10);
std::cin.ignore();
return 0;
}
This program compiled in Mingw_w64, exits with
C:\Users\*>g++ -o test.exe quicktest.cpp -I .\Libraries
C:\Users\THEMAG~1\AppData\Local\Temp\ccszH6xM.o:quicktest.cpp:(.text+0x42):undefined reference to `A<char, 2>::f()'
collect2.exe: error: ld returned 1 exit status
This may just be a lack of knowledge on my part, but this website (at the bottom, first example under members of partial specializations) implies that you can exclude the function definition for a partial specialization, as long as you have declared it, and it will default to using the primary template's definition.
Being able to do this would save me days of work, as I wouldn't have to redefine all of my class's functions. So my question is, what is keeping my code from compiling, and can/how can I specialize my classes for references(I'll still need to do it for pointers) without having to redefine their functions? Is this simply an issue of references changing how the code would have to work, e.g. the primary specialization's function would just shift the reference if it's function was used.
I don't think that this notion in which specialized class templates inherit the implementations of methods from the unspecialized class template is correct. Consider for example std::enable_if. The entire point of this class is to trigger subsitution failure by referencing a type that doesn't exist in a specialized version of the template. If the behavior you described were correct, then this wouldn't work. Or at least, you would need to define enable_if using two specializations instead of a generic and one specialization (which is not the case).
I think this is an "XY" situation: you'd like to be able to do something, but I think more likely you should revise your design so you don't need to do that thing. I can imagine situations where getting the generic template member function would be useful, but it should be relatively rare, and this doesn't strike me as one of those cases.
More likely, if the whole point of your template is to put type T in a point, and putting a point in a point makes no sense, you should just static assert that T is not itself some kind of Point template class. What extra functionality does the specialization give you? Why do you want need a reference/pointer specialization?