G
Guest
Hello all,
I ran into a little problem with recursive templates that I am not sure
what it has to do with, essentially, since I am currently limited in my
access to compilers (namely GCC 4.1) and until now had no chance of testing
the code with others. It may be an implementation detail or even in the
standard (which I have no access to, unfortunately). Or maybe I have hit
one of those cases whose solutions are "undefined" by the standard ...
Anyway, here's the simplified code (the actual code is a lot more involved
and may obfuscate the essentials):
[code:
#include <iostream>
using namespace std;
class my_float {
public:
my_float( float f ): m(f) {}
float get() const { return m; }
protected:
float m;
};
class my_string {
public:
my_string( const char * s ): m(s) {}
const char * get() const { return m; }
protected:
const char * m;
};
class my_type {
public:
my_type(): f(-.6457), s("fv6urtvku") {}
my_type( float _f, const char * _s ): f(_f), s(_s) {}
operator my_float () const { return f; }
operator my_string () const { return s; }
private:
my_float f;
my_string s;
};
// (1) recursion entry
template < typename Value, typename Type1, typename Type2 >
class my_recursion : public my_recursion<Value, Type2, int> {
protected:
typedef my_recursion<Value, Type2, int> base_type;
my_recursion( const Value & v ): base_type(v) {}
public:
operator Type1 () const { return value; }
private:
my_recursion();
};
// (2) partial spec for end of recursion and root of the inheritance tree
template < typename Value, typename Type >
class my_recursion<Value, Type, int> {
protected:
my_recursion( const Value & v ): value(v) {}
public:
operator Type () const { return value; }
protected:
Value value;
private:
my_recursion();
};
// (3)
template < typename Value >
class my_class : public my_recursion<Value, my_float, my_string> {
public:
typedef my_recursion<Value, my_float, my_string> base_type;
my_class( const Value & v ): base_type(v) {}
};
void ff( const my_float & f )
{
cout << "ff() = " << f.get() << endl;
}
void fs( const my_string & s )
{
cout << "fs() = " << s.get() << endl;
}
int main ( int argc, char ** argv )
{
my_type t(-.234354, "zzzdcghzzzz");
my_class<my_type> mc(t);
cout << "sizeof(my_float) = " << sizeof(my_float) << endl
<< "sizeof(my_string) = " << sizeof(my_string) << endl
<< "sizeof(my_type) = " << sizeof(my_type) << endl
<< "sizeof(mc) = " << sizeof(mc) << endl;
ff(mc);
fs(mc);
return 0;
}
--code end]
What happened to me here is that value as defined as protected member variable
in (2), though inherited by (1), is apparently not visible for the latter. The
above written all by hand works perfectly and I suspect that the template class
that is being inherited from in (1) is not consulted for possible inheritable
members. It would be of great help if someone else could test the code with
their compilers and what those complain (if at all).
Thanks & regards,
Christian
I ran into a little problem with recursive templates that I am not sure
what it has to do with, essentially, since I am currently limited in my
access to compilers (namely GCC 4.1) and until now had no chance of testing
the code with others. It may be an implementation detail or even in the
standard (which I have no access to, unfortunately). Or maybe I have hit
one of those cases whose solutions are "undefined" by the standard ...
Anyway, here's the simplified code (the actual code is a lot more involved
and may obfuscate the essentials):
[code:
#include <iostream>
using namespace std;
class my_float {
public:
my_float( float f ): m(f) {}
float get() const { return m; }
protected:
float m;
};
class my_string {
public:
my_string( const char * s ): m(s) {}
const char * get() const { return m; }
protected:
const char * m;
};
class my_type {
public:
my_type(): f(-.6457), s("fv6urtvku") {}
my_type( float _f, const char * _s ): f(_f), s(_s) {}
operator my_float () const { return f; }
operator my_string () const { return s; }
private:
my_float f;
my_string s;
};
// (1) recursion entry
template < typename Value, typename Type1, typename Type2 >
class my_recursion : public my_recursion<Value, Type2, int> {
protected:
typedef my_recursion<Value, Type2, int> base_type;
my_recursion( const Value & v ): base_type(v) {}
public:
operator Type1 () const { return value; }
private:
my_recursion();
};
// (2) partial spec for end of recursion and root of the inheritance tree
template < typename Value, typename Type >
class my_recursion<Value, Type, int> {
protected:
my_recursion( const Value & v ): value(v) {}
public:
operator Type () const { return value; }
protected:
Value value;
private:
my_recursion();
};
// (3)
template < typename Value >
class my_class : public my_recursion<Value, my_float, my_string> {
public:
typedef my_recursion<Value, my_float, my_string> base_type;
my_class( const Value & v ): base_type(v) {}
};
void ff( const my_float & f )
{
cout << "ff() = " << f.get() << endl;
}
void fs( const my_string & s )
{
cout << "fs() = " << s.get() << endl;
}
int main ( int argc, char ** argv )
{
my_type t(-.234354, "zzzdcghzzzz");
my_class<my_type> mc(t);
cout << "sizeof(my_float) = " << sizeof(my_float) << endl
<< "sizeof(my_string) = " << sizeof(my_string) << endl
<< "sizeof(my_type) = " << sizeof(my_type) << endl
<< "sizeof(mc) = " << sizeof(mc) << endl;
ff(mc);
fs(mc);
return 0;
}
--code end]
What happened to me here is that value as defined as protected member variable
in (2), though inherited by (1), is apparently not visible for the latter. The
above written all by hand works perfectly and I suspect that the template class
that is being inherited from in (1) is not consulted for possible inheritable
members. It would be of great help if someone else could test the code with
their compilers and what those complain (if at all).
Thanks & regards,
Christian