By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
429,480 Members | 771 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,480 IT Pros & Developers. It's quick & easy.

Trouble specializing a member function in a template class

P: n/a
/* --------------------------------------------------------------------------
Hello,

I was experimenting with class templates and specializing member
functions and came across a simple problem which I can't figure out.
I have a simple class C with 2 template member objects, and a function
print() that prints the value of these objects. I defined a
specialization of print() for C<string, char> which is called
correctly. Then I wanted to define a specialization of print() that
would be called for C<class T, int>, where T is any type. I couldn't
get this code to compile, let alone run, and tried various ways to
make it work. The full source is below.

Is there a nice solution to this problem? I read somewhere (can't
recall where) that you can't specialize member functions for classes
without specializing the whole class, and yet the C<string,
char>::print() specialization works.

Jeff
---------------------------------------------------------------------------
*/
#include <iostream>
#include <string>
using namespace std;
template<class A, class B>
class C {
public:
C(A a, B b) : a_(a), b_(b) {}

A a_;
B b_;
void print() const;
};
// Template definition of print()
template<class A, class B> void C<A, B>::print() const
{ cout << "Output: " << a_ << ", " << b_ << endl; }
// Full specialization of print() for <string, char> types
template<> void C<string, char>::print() const {
cout << "C<string, char> output: " << a_ << " ... " << b_ << endl;
}
// Trouble here ---------------------------------------------
// the following partial specialization gives the compiler error:
// a.cpp:33: no `void C<A, int>::print() const' member function
declared in class `C<A, int>'
// a.cpp:33: template definition of non-template `void C<A,
int>::print() const'
// (using GCC 3.2)

// if B is type int, call this...
//template<class A, int> //doesn't work
//template<class A, class B> // doesn't work
template<class A> // doesn't work
void
C<A, int>::print() const {
cout << "C<A, int> output: ";
for (int i=0; i<b_; ++i) { cout << a_ << endl; }
cout << endl;
}
// end of Trouble -------------------------------------------
int main() {
// calls template definition, prints "Output: a, 1.23456"
C<char, float> myC('a', 1.23456);
myC.print();
cout << endl;

// calls full specialization successfully, prints "C<string, char>
output: hello there ... b"
C<string, char> C2("hello there", 'z');
C2.print();
cout << endl;

// should call partial specialization, want it to print "C<A, int>
output: boo!boo!boo!boo!boo!"
C<string, int> pc("boo!", 5);
pc.print();
cout << endl;

return 0;
}
Jul 22 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Jeff wrote in news:7b**************************@posting.google.c om:
I was experimenting with class templates and specializing member
functions and came across a simple problem which I can't figure out.
I have a simple class C with 2 template member objects, and a function
print() that prints the value of these objects. I defined a
specialization of print() for C<string, char> which is called
correctly. Then I wanted to define a specialization of print() that
would be called for C<class T, int>, where T is any type. I couldn't
get this code to compile, let alone run, and tried various ways to
make it work. The full source is below.

Your problem is that you are trying to create a partial specialization
of a function (non-static member in this case, but that doesn't matter).
For some reason this is not allowed by the language (possibly the
standards committee thought overloading was enough). The workaround
as always is to add another layey of indirection (see below).
Is there a nice solution to this problem? I read somewhere (can't
recall where) that you can't specialize member functions for classes
without specializing the whole class, and yet the C<string,
char>::print() specialization works.
Yup explicit specialization's (template <>) are allowed.


#include <iostream>
#include <typeinfo>

struct example
{
template < typename U, typename V >
void patialy_specialized( U const &u, V const &v );

};

/* helper class
*/
template < typename U, typename V >
struct example_patialy_specialized
{
static void apply( example * that, U const &u, V const &v )
{
std::cerr
<< "default version "
<< typeid( U ).name()
<< " - "
<< typeid( V ).name()
<< "\n"
;
}
};

/* defenition of template method, indirects through the
"helper" above or (importantly) one of its specializations.
*/
template < typename U, typename V >
inline void example::patialy_specialized( U const &u, V const &v)
{
return example_patialy_specialized< U, V >::apply( this, u, v );
}

/* demo specialization of the "helper"
*/
template < typename U >
struct example_patialy_specialized< U, int >
{
static void apply( example * that, U const &arg, int )
{
std::cerr << "U int version " << typeid( U ).name() << "\n";
}
};

int main()
{
example ex;
double d = 1;

ex.patialy_specialized( d, d ); // default
ex.patialy_specialized( d, 1 ); // partial specialization
}

HTH

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #2

P: n/a
Thanks Rob, got it. I guess I'd need to make the
example_patialy_specialized<U, V> template a friend inside the
example<U, V> template to access any of the private member data. Kind
of unfortunate, it clutters up what seems to be a fairly simple
problem (mind you, I have no need for it yet, just testing)... but
that's templates for you.

Thanks again, a big help.
Jeff
Jul 22 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.