How to Create a Template Function Within a Class? (C++)

How to create a template function within a class? (C++)

Your guess is the correct one. The only thing you have to remember is that the member function template definition (in addition to the declaration) should be in the header file, not the cpp, though it does not have to be in the body of the class declaration itself.

C++ template function inside a non-template class

As people have noted in the comments, there's no problem doing so.

One aspect to watch out for is where to put the definition of the method templatefunction. For the time being (see the ISO cpp FAQ), you should consider placing it in the header file, which is different than what you'd probably do with the definition of the other methods. Thus you'd have example.hpp:

class example
{
public:
example();
~example();
template<typename T> void templatefunction(T);
void nontemplatefunction(string x);
};

template<typename T> void example::templatefunction(T)
{

}

and then example.cpp:

example::example(){}

void example::nontemplatefunction(string x)
{

}

Template function inside template class

Write this:

template <class T>
template <class U>
void MyClass<T>::foo() { /* ... */ }

Instantiating nested template function in template class

You can do it with this:

template int A<int>::b<short>(short r);

How to define template function within template class in *.inl file

Here's your definition:

template <typename T1, typename T2>
template <typename E>
void SomeClass<T1, T2>::extraTypedMethod(E & e)
{
}

How to get a C++ template class to invoke another class' methods?

A step by step solution:
all examples uses the following class and foo function

#include <iostream>
class A
{
public:
void foo(){std::cout<<"foo"<<std::endl;}
};

this sample works without template: just calling the calling A::foo with pointer to A and pointer to A::foo:

class B
{
public:
A *a;
void (A::*p)();

void bar()
{
(a->*p)(); //call A::foo
}
};
int main(void)
{
A a;
B b;
b.a = &a;
b.p = &A::foo;
b.bar();
return 0;
}

The following sample added template class T, the pointer to foo method derived from T.

template <class T>
class C
{
public:
T* t;
void (T::*p)();
C(T &o) : t(&o){}
void bar()
{
(t->*p)();
}
};
int main(void)
{
A a;
C<A> c(a);
c.p = &A::foo;
c.bar();
return 0;
}

in the following, the method pointer was templated too, but I don't see how can it be used since you should know how many argument to give it, but anyway:

template <class T, typename F>
class D
{
public:
T* t;
F p;
D(T &o, F pf) : t(&o),p(pf){}
void bar()
{
(t->*p)();
}
};
int main(void)
{
A a;
D<A, void (A::*)()> d(a, &A::foo);
d.bar();
return 0;
}

Where to define C++ class member template function and functors that instantiate it?

General rule:

If foo::doSomething() is used outside foo.cpp (i.e. if it's public or protected, usually), it must go in the header.

If not, putting in in the cpp file is perfectly ok, and even a good idea (as it keeps the clutter away from the header file).

So, if the functors are only used in the cpp file, by all means put the template function there too. One can always refactor things later if this changes.

Defining a Single Template for a Member Function within a Class Template with Both Templates Used in Member Function

Both the two sets of template parameters are required to define the member template.

(emphasis mine)

If the enclosing class declaration is, in turn, a class template, when a member template is defined outside of the class body, it takes two sets of template parameters: one for the enclosing class, and another one for itself:

E.g.

template<typename A>
template<typename B>
void foo<A>::boo(B value) {}

C++ specialization of template function inside template class

So, I'm taking a different approach to answering your question. I'm going to start from something that sort of does what you want, and works. And then maybe we can figure out how to permute it into something closer to what you really want:

#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';
}

Here is another idea that sort of works, and isn't exactly what you want, but is closer. I think you've thought of it yourself. It's also rather ugly in the way it uses type deduction.

#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';
}

I would recommend declaring getThingFunctor and friendlyGetThing in a semi-private utility namespace.



Related Topics



Leave a reply



Submit