- C specialization of template function inside template class
- template <class c1> class X {
- public:
- template<typename returnT> returnT getAThing(std::string param);
- static std::string getName();
- private:
- c1 theData;
- };
- // This works ok...
- template <class c1> std::string X<c1>::getName() {
- return c1::getName();
- }
- // This blows up with the error:
- // error: prototype for 'int X<c1>::getAThing(std::string)' does not match any in class 'X<c1>'
- template <class c1> template <typename returnT> int X<c1>::getAThing(std::string param) {
- return getIntThing(param); // Some function that crunches on param and returns an int.
- }
- // More specialized definitions of getAThing() for other types/classes go here...
- class Y {
- public:
- static std::string getName() { return "Y"; }
- };
- int main(int argc, char* argv[])
- {
- X<Y> tester;
- int anIntThing = tester.getAThing<int>(std::string("param"));
- cout << "Name: " << tester.getName() << endl;
- cout << "An int thing: " << anIntThing << endl;
- }
- #include <string>
- #include <iostream>
- int getIntThing(const ::std::string ¶m);
- template <typename returnT>
- returnT getThingFree(const ::std::string ¶m);
- template <>
- int getThingFree<int>(const ::std::string ¶m)
- {
- return getIntThing(param);
- }
- // More specialized definitions of getAThing() for other types/classes
- // go here...
- template <class c1> class X {
- public:
- template<typename returnT> returnT getAThing(std::string param);
- static std::string getName();
- private:
- c1 theData;
- };
- // This works ok...
- template <class c1> std::string X<c1>::getName() {
- return c1::getName();
- }
- // This also works, but it would be nice if I could explicitly specialize
- // this instead of having to explicitly specialize getThingFree.
- template <class c1>
- template <class RT>
- RT X<c1>::getAThing(std::string param) {
- // Some function that crunches on param and returns an RT.
- // Gosh, wouldn't it be nice if I didn't have to redirect through
- // this free function?
- return getThingFree<RT>(param);
- }
- class Y {
- public:
- static std::string getName() { return "Y"; }
- };
- int main(int argc, char* argv[])
- {
- using ::std::cout;
- X<Y> tester;
- int anIntThing = tester.getAThing<int>(std::string("param"));
- cout << "Name: " << tester.getName() << 'n';
- cout << "An int thing: " << anIntThing << 'n';
- }
- #include <string>
- #include <iostream>
- template <class c1> class X;
- int getIntThing(const ::std::string ¶m)
- {
- return param.size();
- }
- // You can partially specialize this, but only for the class, or the
- // class and return type. You cannot partially specialize this for
- // just the return type. OTOH, specializations will be able to access
- // private or protected members of X<c1> as this class is declared a
- // friend.
- template <class c1>
- class friendlyGetThing {
- public:
- template <typename return_t>
- static return_t getThing(X<c1> &xthis, const ::std::string ¶m,
- return_t *);
- };
- // This can be partially specialized on either class, return type, or
- // both, but it cannot be declared a friend, so will have no access to
- // private or protected members of X<c1>.
- template <class c1, typename return_t>
- class getThingFunctor {
- public:
- typedef return_t r_t;
- return_t operator()(X<c1> &xthis, const ::std::string ¶m) {
- return_t *fred = 0;
- return friendlyGetThing<c1>::getThing(xthis, param, fred);
- }
- };
- template <class c1> class X {
- public:
- friend class friendlyGetThing<c1>;
- template<typename returnT> returnT getAThing(std::string param) {
- return getThingFunctor<c1, returnT>()(*this, param);
- }
- static std::string getName();
- private:
- c1 theData;
- };
- // This works ok...
- template <class c1> std::string X<c1>::getName() {
- return c1::getName();
- }
- class Y {
- public:
- static std::string getName() { return "Y"; }
- };
- template <class c1>
- class getThingFunctor<c1, int> {
- public:
- int operator()(X<c1> &xthis, const ::std::string ¶m) {
- return getIntThing(param);
- }
- };
- // More specialized definitions of getAThingFunctor for other types/classes
- // go here...
- int main(int argc, char* argv[])
- {
- using ::std::cout;
- X<Y> tester;
- int anIntThing = tester.getAThing<int>(std::string("param"));
- cout << "Name: " << tester.getName() << 'n';
- cout << "An int thing: " << anIntThing << 'n';
- }
- template <> template <> int X<Y>::getAThing<int>(std::string param) {
- return getIntThing(param); // Some function that crunches on param and returns an int.
- }
- template <>
- template <class T>
- int X<T>::template getAThing<int>(std::string param)
- {
- return getIntThing(param);
- }
- #include <iostream>
- #include <string>
- using namespace std;
- // IMPORTANT NOTE: AdaptingFunctor has no access to the guts of class X!
- // Thus, this solution is somewhat limited.
- template<typename t1> class AdaptingFunctor {
- public:
- t1 operator() (string param);
- };
- // Can specialize AdaptingFunctor for each type required:
- template<> int AdaptingFunctor<int>::operator() (string param)
- {
- return param.size(); // <=== Insert required type-specific logic here
- }
- // Additional specializations for each return type can go
- // here, without requiring specialization of class c1 for X...
- template <class c1> class X {
- public:
- template<typename returnT> returnT getAThing(std::string param)
- {
- AdaptingFunctor<returnT> adapter;
- return adapter(param);
- }
- static std::string getName();
- private:
- c1 theData;
- };
- // Template definition of class method works ok...
- template <class c1> std::string X<c1>::getName() {
- return c1::getName();
- }
- class Y {
- public:
- static std::string getName() { return "Y"; }
- };
- int main(int argc, char* argv[])
- {
- X<Y> tester;
- int anIntThing = tester.getAThing<int>(std::string("param"));
- cout << "Name: " << tester.getName() << endl;
- cout << "An int thing: " << anIntThing << endl;
- }
- template <class T1>
- struct MyClass {
- template <class T2>
- void MyFunction();
- };
- template <class T1>
- template <class T2>
- void MyClass<T1>::MyFunction() { // NOTE: NO T2 on this line.
- // Code goes here
- }